So I wanted the equivalent of doing an sql not in query such as this:
select * from test where id not in (1,2,3);
Initially I was thinking more in SQL, and it took me an hour to understand the philosophy behind Elasticsearch, the query builder, and the underlying rest API.
I have come up with the following which however seems very inefficient:
public <T> MyQueryBuilder notIn(String field, List<String> values) {
if (values != null & values.size() > 0) {
Iterator<String> it = values.iterator();
while(it.hasNext()){
MatchQueryBuilder match = new MatchQueryBuilder(field, it.next());
match.operator(Operator.OR);
boolQueryBuilder.mustNot(match);
}
}
return this;
}
And this generates the following rest call body:
{
"bool" : {
"must_not" : [ {
"match" : {
"myId" : {
"query" : "b5359d78-5e0e-4b09-af2c-d4c921ea6a15",
"operator" : "OR"
}
}
}, {
"match" : {
"myId" : {
"query" : "e679ce6d-a7a1-48a0-b06e-54752fbd7e31",
"operator" : "OR"
}
}
} ]
}
}
So is there a better more efficient way? Update: Efficient might have been the wrong word. A more concise/compact expression....
Thanks!
Update
I also tried the following but it does not work like an sql not in expression:
{ "query" : {
"bool" : {
"must_not" : {
"bool": {
"filter": [
{
"terms": {
"myId": [
"c1928da6-80d0-475a-9025-b3ebd934a576" ,
"d2",
"d3",
"d4"
]
}
}
]
}
},
"must_not" : {
"match" : {
"myId" :
}
}
}
}
}
Update 2
I think the following actually works, and works better:
{ "query" : {
"bool" : {
"must_not" : {
"bool": {
"filter": [
{
"terms": {
"myId": [
"c1928da6-80d0-475a-9025-b3ebd934a576" ,
"d2",
"d3",
"d4"
]
}
}
]
}
}
}
}
}
This does not seem to work even though the notation seems to be more concise .
public <T> CoolQueryBuilder notInV2(String field, List<String> values) {
if (values != null & values.size() > 0) {
//boolQuery() = constructor for boolean query
boolQueryBuilder.mustNot(boolQuery().filter(termsQuery(field, values)));
}
return this;
}