Reputation: 77
I have a problem with elasticsearch query in Java This is my code:
BoolQueryBuilder qb = QueryBuilders.boolQuery();
for example:
if (myFilter.getTerm1() != null) {
qb.should(QueryBuilders.termsQuery("myfield1", myFilter.getTerm1()));
}
if (myFilter.getTerm2() != null) {
qb.should(QueryBuilders.termsQuery("myfield2", myFilter.getTerm2()));
}
qb.minimumShouldMatch("100%");
SearchRequest request = op.searchRequest(classTarget(MyClass.class));// this just create a new SearchRequest
sourceBuilder.query(QueryBuilders.simpleQueryStringQuery(qb.toString()));
sourceBuilder.from((pageNumber));
sourceBuilder.size(pageSize);
request.source(sourceBuilder);
The problem is that this gives me back all the result that matches with “myfield1 OR myfield2”, but I need to have all the result that matches “myfield1 AND myfield2”
For example if I have 2 documents, one with
myfield1 = “Foo” and myfield2 = “Test”
and the other with:
myfield1 = “Elastic” and myfield2 = “Search”
if I made a query with myfield1 = “Foo” and myfield2 = “Search” I expect to have no results, but I have both documents.
I also tried to use “must” instead of “should” and I tried to set the default operator to “AND” in sourceBuilder but in this case I have no results at all, also if the query should return something.
this is the print of "request"
Query request: SearchRequest{searchType=QUERY_THEN_FETCH, indices=[myIndex], indicesOptions=IndicesOptions[ignore_unavailable=false, allow_no_indices=true, expand_wildcards_open=true, expand_wildcards_closed=false, allow_aliases_to_multiple_indices=true, forbid_closed_indices=true, ignore_aliases=false], types=[data], routing='null', preference='data', requestCache=null, scroll=null, maxConcurrentShardRequests=0, batchedReduceSize=512, preFilterShardSize=128, allowPartialSearchResults=null, source={"from":0,"size":100,"query":{"simple_query_string":{"query":"{\n \"bool\" : {\n \"should\" : [\n {\n \"terms\" : {\n \"myfield1.keyword\" : [\n \"foo\"\n ],\n \"boost\" : 1.0\n }\n },\n {\n \"terms\" : {\n \"myfield2.keyword\" : [\n \"search\"\n ],\n \"boost\" : 1.0\n }\n }\n ],\n \"adjust_pure_negative\" : true,\n \"minimum_should_match\" : \"100%\",\n \"boost\" : 1.0\n }\n}","flags":-1,"default_operator":"or","analyze_wildcard":false,"auto_generate_synonyms_phrase_query":true,"fuzzy_prefix_length":0,"fuzzy_max_expansions":50,"fuzzy_transpositions":true,"boost":1.0}}}}
Upvotes: 1
Views: 319
Reputation: 217304
If you need AND logic, then you can rule out should
. You need must
instead and probably with a match
query instead of term
(as I don't think you need exact matching). Try this instead:
if (myFilter.getTerm1() != null) {
qb.must(QueryBuilders.matchQuery("myfield1", myFilter.getTerm1()));
}
if (myFilter.getTerm2() != null) {
qb.must(QueryBuilders.matchQuery("myfield2", myFilter.getTerm2()));
}
also remove qb.minimumShouldMatch("100%");
Also this QueryBuilders.simpleQueryStringQuery(qb.toString())
should result in an error, as you cannot serialize a bool query into a simple_query_string
query, it's just not meant for that purpose.
Simply change your statement to this one:
sourceBuilder.query(qb);
If you print out your query you'll see the following, which is most probably not what you want:
{
"from": 0,
"size": 100,
"query": {
"simple_query_string": {
"query": "{\n \"bool\" : {\n \"should\" : [\n {\n \"terms\" : {\n \"myfield1.keyword\" : [\n \"foo\"\n ],\n \"boost\" : 1.0\n }\n },\n {\n \"terms\" : {\n \"myfield2.keyword\" : [\n \"search\"\n ],\n \"boost\" : 1.0\n }\n }\n ],\n \"adjust_pure_negative\" : true,\n \"minimum_should_match\" : \"100%\",\n \"boost\" : 1.0\n }\n}",
"flags": -1,
"default_operator": "or",
"analyze_wildcard": false,
"auto_generate_synonyms_phrase_query": true,
"fuzzy_prefix_length": 0,
"fuzzy_max_expansions": 50,
"fuzzy_transpositions": true,
"boost": 1
}
}
}
Upvotes: 1