@Ali
BaseQueryBuilder is the foundation, the sub-classes give the details.
If you want to wire, then you misunderstand the way how search with
facets etc. works. What you want is not a chaining of queries, but
instead a filtering of the set. This filtering is important as it
narrows the resultset where the search is applied onto.
In java-api one usually starts with getting an SearchRequestBuilder,
then puts an (only one) query to it and then adds filters to it.
Simply said something like this:
private SearchRequestBuilder initBuilder(SearchRequestBuilder srq) {
QueryStringQueryBuilder query =
QueryBuilders.queryString(queryString).useDisMax(true).defaultOperator(operator);
//boosting
for (Map.Entry<String, Float> e : boostFields.entrySet()) {
query.field(e.getKey(), e.getValue());
}
srq.setQuery(query); <- only this is the Query!!!
srq.addFields(fields.toArray(new String[fields.size()]));
//sorting
for (Map.Entry<String, SortOrder> e : sortMap.entrySet()) {
srq.addSort(e.getKey(), e.getValue());
}
//filtering <- this is what you want
AndFilterBuilder myFilters = FilterBuilders.andFilter();
if (termFilters.size() > 0) {
for (Map.Entry<String, String> e : termFilters.entrySet())
{
myFilters.add(FilterBuilders.termFilter(e.getKey(),
e.getValue()));
}
srq.setFilter(myFilters);
}
for (String facet : termFacets.keySet()) {
TermsFacetBuilder tf =
FacetBuilders.termsFacet(facet).field(facet).size(termFacets.get(facet)).order(getTermsComparator());
if (termFilters.size() > 0) {
tf.facetFilter(myFilters);
}
srq.addFacet(tf);
}
return srq;
}
please note that this is just an example from my main usage within an
wicket-dataprovider, but it should you show how to tighten things. Be
also sure to cleanse any data you pass to ES prior giving it to the
query:
/**
* function to escape the string from bad chars for the search
*
* @param str the String that should be escaped
* @return an escaped String
*/
@SuppressWarnings({"ConstantConditions"})
public static String smartEscapeQuery(String str) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (c == '\' || c == '+' || c == '-' || c == '!' || c ==
'(' || c == ')' || c == ':'
|| c == '^' || c == '[' || c == ']' || c == '"'
|| c == '{' || c == '}' || c == '~'
|| c == '?' || c == '|' || c == '&' || c == ';'
|| (!Character.isSpaceChar(c) &&
Character.isWhitespace(c))) {
sb.append('\');
}
sb.append(c);
}
return sb.toString();
}
Best,
KB
PS: don't even think of putting a own wrapper around ES<->Java as you
will not even come close to its speed and stability (ES JavaApi joins
the es node network, meaning full clustering, optimized data and
request traveling etc;)
On 21 Nov., 22:20, Ali loghm...@gmail.com wrote:
Hi mates,
I have been asked to use elasticsearch JAVA API (I personally love its
REST API, but I am not the decision maker here). I have been
struggling with finding a good set of classes/methods to build
comprehensive queries. I have already looked into "BaseQueryBuilder"
and its implementing classes but none allow wiring of multiple query
clauses!
I thought maybe the JAVA API is not there yet in terms of milestones,
product management, resources .. (I believe what the team has
delivered so far is AWESOME, and JAVA API is really just a 2010- last
decade thing). But, like I said I am asked to use JAVA API. So, please
help me to find a solution for this. Either I have to develop a JAVA
REST wrapper around the JSON REST API or find a way to use the current
JAVA API to build comprehensive queries.
Any help is very much appreciated!
Thanks,
Ali