12.5.4. CompassQuery and CompassQueryBuilder Compass::Core comes with the CompassQueryBuilder interface, which provides programmatic API for building a query. The query builder creates a CompassQuery which can than be used to add sorting and executing the query. Working with objects Compass - Java Search Engine 108Using the CompassQueryBuilder, simple queries can be created (i.e. eq, between, prefix, fuzzy), and more complex query builders can be created as well (such as a boolean query, multi-phrase, and query string). The following code shows how to use a query string query builder and using the CompassQuery add sorting to the result. CompassHits hits = session.createQueryBuilder() .queryString("+name:jack +familyName:london") .setAnalyzer("an1") // use a different analyzer .toQuery() .addSort("familyName", CompassQuery.SortPropertyType.STRING) .addSort("birthdate", CompassQuery.SortPropertyType.INT) .hits(); Another example for building a query that requires the name to be jack, and the familyName not to be london: CompassQueryBuilder queryBuilder = session.createQueryBuilder(); CompassHits hits = queryBuilder.bool() .addMust( queryBuilder.term("name", "jack") ) .addMustNot( queryBuilder.term("familyName", "london") ) .toQuery() .addSort("familyName", CompassQuery.SortPropertyType.STRING) .addSort("birthdate", CompassQuery.SortPropertyType.INT) .hits(); CompassQuery can also be created using the Compass instance, without the need to construct a CompassSession. They can then stored and used safely by multiple sessions (in a multi threaded environment) by attaching them to the current session using CompassQuery#attach(CompssSession) API. Note that sorted resource properties / meta-data must be stored and not_analyzed. Also sorting requires more memory to keep sorting properties available. For numeric types, each property sorted requires four bytes to be cached for each resource in the index. For String types, each unique term needs to be cached. When a query is built, most of the queries can accept an Object as a parameter, and the name part can be more than just a simple string value of the meta-data / resource-property. If we take the following mapping for example: <class name="eg.A" alias="a"> <id name="id" /> <property name="familyName"> <meta-data>family-name</meta-data> </property> <property name="date"> <meta-data converter-param="YYYYMMDD">date-sem</meta-data> </property> </class> The mapping defines a simple class mapping, with a simple string property called familyName and a date property called date. With the CompassQueryBuilder, most of the queries can directly work with either level of the mappings. Here are some samples: CompassQueryBuilder queryBuilder = session.createQueryBuilder(); // The following search will result in matching "london" against "familyName" CompassHits hits = queryBuilder.term("a.familyName.family-name", "london").hits(); // The following search will use the class property meta-data id, which in this case // is the first one (family-name). If there was another meta-data with the family-name value, // the internal meta-data that is created will be used ($/a/familyName). CompassHits hits = queryBuilder.term("a.familyName", "london").hits(); // Here, we provide the Date object as a parameter, the query builder will use the Working with objects Framework (2.2.0 GA)// converter framework to convert the value (and use the given parameter) CompassHits hits = queryBuilder.term("a.date.date-sem", new Date()).hits(); // Remmember, that the alias constraint will not be added automatically, so // the following query will cause only family-name with the value "london" of alias "a" CompassHits hits = queryBuilder.bool() .addMust( queryBuilder.alias("a") ) .addMust( queryBuilder.term("a.familyName", "london") ) .toQuery().hits(); When using query strings and query parsers, Compass enhances Lucene query parser to support custom formats (for dates and numbers, for example) as well as support dot path notation. The query: a.familyname.family-name:london will result in a query matching on familyName to london as well as wrapping the query with one that will only match the a alias.