Last updated by gorshing 1 year ago
Query Builder
Searchable Plugin comes with a builder, which makes programmatic queries Groovy, baby.When you pass a closure to one of the search methods, you are using the query builder.TODO the query builder needs a reference section
It builds on Compass
The query builder syntax mirrors Compass's own CompassQueryBuilder: to get the most out of the Searchable Plugin's query builder, you should take a moment to familiarise yourself with it.And makes it better
The plugin's Groovy query builder improves on the raw Compass experience in a few ways. First it relieves you of the burden to call toQuery() when using the various specific builders obtained from calling some CompassQueryBuilder methods, and it allows you to easily nest these specific builders using closures.It also simplifies the job of constructing boolean queries by not requiring you to explicitly create a boolean builder and add "should" clauses. You still need to explicitly add must and must not clauses, but other clauses in a boolean context are assumed to be should clauses.The rules
The methods you can invoke depend on the current context. In the outer-most context you can invoke CompassQueryBuilder methods.Within nested contexts (which are created by nested closures) you can call both CompassQueryBuilder methods and whatever methods the current nested builder supports.The builder also allows you to call Compass's various query builders' options "setters" using a literal options Map as the last argument, instead of requiring method invocations.The builder shortens a few method names too, so the CompassBooleanQueryBuilder addMust, addShould, and addMustNot methods can be shortened to must, should, and mustNot (and as already mentioned you typically don't need to use should because any clause that is not a must or mustNot is assumed to be should) and the CompassQuery addSort method can be shortedned to sort.And finally because it's Groovy, you have the language at your disposal so you can use control flow, loops, variables etc.Enough theory, let's explore some examples.By Example
Say you want to search for items in the index where "pages" is less than 50 and "type" is "poetry". A String query for this might look like "pages:[* TO 50] type:poetry".Using the builder you would dosearch { // <-- create an implicit boolean query
lt("pages", 50) // <-- uses CompassQueryBuilder#lt, and adds a boolean "should" clause
term("type", "poetry") // <-- uses CompassQueryBuilder#term, and adds a boolean "should" clause
}search { // <-- creates an implicit boolean query
lt("pages", 50) // <-- uses CompassQueryBuilder#lt, and adds a boolean "should"
must(term("type", "poetry")) // <-- uses CompassQueryBuilder#term, adds a boolean "must"
}search { // <-- creates an implicit boolean query
lt("pages", 50) // <-- uses CompassQueryBuilder#lt, and adds a boolean "should"
must(term("type", "poetry")) // <-- uses CompassQueryBuilder#term, adds a boolean "must"
mustNot(term("theme", "war")) // <-- uses CompassQueryBuilder#term, adds a boolean "mustNot"
}search { // <-- creates an implicit boolean query
must(queryString("all hands on deck")) // <-- uses CompassQueryBuilder#queryString, and adds a boolean must
lt("pages", 50) // <-- uses CompassQueryBuilder#lt, and adds a boolean "should"
must(term("type", "poetry")) // <-- uses CompassQueryBuilder#term, adds a boolean "must"
mustNot(term("theme", "war")) // <-- uses CompassQueryBuilder#term, adds a boolean "mustNot"
}search { // <-- creates an implicit boolean query
must(queryString("all hands on deck") { // <-- creates a nested CompassQueryStringBuilder context
useAndDefaultOperator() // <-- calls CompassQueryStringBuilder#useAndDefaultOperator
setDefaultSearchProperty("body") // <-- calls CompassQueryStringBuilder#setDefaultSearchProperty
}) // <-- added as boolean must to surrounding boolean
lt("pages", 50) // <-- uses CompassQueryBuilder#lt, and adds a boolean "should"
must(term("type", "poetry")) // <-- uses CompassQueryBuilder#term, adds a boolean "must"
mustNot(term("theme", "war")) // <-- uses CompassQueryBuilder#term, adds a boolean "mustNot"
}search { // <-- creates an implicit boolean query
must(queryString("all hands on deck", [useAndDefaultOperator: true, defaultSearchProperty: "body"]))
// ^^ add a "must" nested query string, calling useAndDefaultOperator() and setDefaultSearchProperty("body")
// on the CompassQueryStringBuilder
lt("pages", 50) // <-- uses CompassQueryBuilder#lt, and adds a boolean "should"
must(term("type", "poetry")) // <-- uses CompassQueryBuilder#term, adds a boolean "must"
mustNot(term("theme", "war")) // <-- uses CompassQueryBuilder#term, adds a boolean "mustNot"
}search { // <-- creates an implicit boolean query
must(multiPhrase("body", [slop: 2]) { // <-- creates a nested CompassMultiPhraseQueryBuilder context, calling setSlop(2)
add("all") // <-- calls CompassMultiPhraseQueryBuilder#add
add("hands") // <-- calls CompassMultiPhraseQueryBuilder#add
add("on")
add("deck")
}) // <-- adds multiPhrase as boolean "must"
lt("pages", 50) // <-- uses CompassQueryBuilder#lt, and adds a boolean "should"
must(term("type", "poetry")) // <-- uses CompassQueryBuilder#term, adds a boolean "must"
mustNot(term("theme", "war")) // <-- uses CompassQueryBuilder#term, adds a boolean "mustNot"
}search { // <-- creates an implicit boolean query
must(multiPhrase("body", [slop: 2]) { // <-- creates a nested CompassMultiPhraseQueryBuilder context, and calls setSlop(2)
add("all") // <-- calls CompassMultiPhraseQueryBuilder#add
add("hands") // <-- calls CompassMultiPhraseQueryBuilder#add
add("on")
add("deck")
}) // <-- adds multiPhrase as boolean "must"
must { // <-- creates an nested boolean query, implicitly
ge("pages", 50) // <-- uses CompassQueryBuilder#ge, adds a boolean "should"
lt("pages", 50, [boost: 1.5]) // <-- uses CompassQueryBuilder#lt, calls setBoost(1.5f), adds a boolean "should"
} // <-- adds nested boolean as "must" clause to outer boolean
must(term("type", "poetry")) // <-- uses CompassQueryBuilder#term, adds a boolean "must"
mustNot(term("theme", "war")) // <-- uses CompassQueryBuilder#term, adds a boolean "mustNot"
ge("publishedDate", new Date() - 28)
sort(CompassQuery.SortImplicitType.SCORE) // <-- uses CompassQuery#addSort
sort("authorSurname", CompassQuery.SortPropertyType.STRING) // <-- uses CompassQuery#addSort
}


