Java – Elasticsearch matches the complete array of terms

Elasticsearch matches the complete array of terms… here is a solution to the problem.

Elasticsearch matches the complete array of terms

I need to match the full phrase with Elasticsearch.
Only documents that have arrays containing the same elements should be returned.
There should be no more elements or subsets of elements in the document array.
The order of the elements does not matter.

Example:

 filter:
   id: ["a", "b"]

documents:  
   id: ["a", "b"] -> match  
   id: ["b", "a"] -> match  
   id: ["a"] -> no match  
   id: ["a", "b", "c"] -> no match  

Eventually I want to implement queries using a Java advanced REST client, although the elasticsearch DSL example will do.

Solution

I’d like to suggest that once your requirements change (for example, let’s say you have an array of six items to match), it prevents you from maintaining a long list of “must” conditions. I’ll rely on a script query, which may seem overdesigned, but can easily create a search template from it ( https://www.elastic.co/guide/en/elasticsearch/reference/7.5/search-template.html)。

{
"query": {
    "bool": {
      "filter": {
        "script": {
          "script": {
            "source": """
              def ids = new ArrayList(doc['id.keyword']);
              def param = new ArrayList(params.terms);
              def isSameSize = ids.size() == param.size();
              def isSameContent = ids.containsAll(param);
              return isSameSize && isSameContent
            """,
            "lang": "painless",
            "params": {
              "terms": [ "a", "b" ]
            }
          }
        }
      }
    }
  }
}

That way, the only thing you need to change is the value of the terms parameter.

Related Problems and Solutions