elasticsearch

Elasticsearch Conditional based querying


I'm working with Elasticsearch and have documents with fields that can be empty (""). Here's an example of the document structure:

    [
          {
            "company_code": "ABC",
            "client_id": "12345",
            "section": "abc",
            "module": "substitute",
            "priority": "1"
          },
          {
            "company_code": "ABC",
            "client_id": "",
            "section": "abc",
            "module": "buy_it_again_products",
            "priority": 1
          }
          {
            "company_code": "",
            "client_id": "",
            "section": "abc",
            "module": "buy_it_again_products",
            "priority": 1
          }
    ]

I need to create an Elasticsearch query that follows these conditions:

  1. When company_code, client_id, and section are given, return documents matching all three fields with non-empty values.
  2. If no documents match the first condition, then only return documents where company_code and section match, but client_id is empty ("").
  3. If no documents match the first and second conditions, then only return documents where only section matches, and both company_code and client_id are empty ("").

The response should include documents satisfying only one condition according to the priority listed above. I have tried the following query and also msearch.

{
  "query": {
    "bool": {
      "should": [
        {
          "bool": {
            "must": [
              { "term": { "company_code": "ABC" } },
              { "term": { "client_id": "12345" } },
              { "term": { "section": "abc" } }
            ],
            "boost": 100
          }
        },
        {
          "bool": {
            "must": [
              { "term": { "company_code": "ABC" } },
              { "term": { "section": "abc" } },
              { "term": { "client_id": "" } }
            ],
            "boost": 20
          }
        },
        {
          "bool": {
            "must": [
              { "term": { "section": "abc" } },
              { "term": { "company_code": "" } },
              { "term": { "client_id": "" } }
            ],
            "boost": 1
          }
        }
      ],
      "minimum_should_match": 1
    }
  },
  "sort": [
    { "_score": "desc" }
  ]
}

The issue with this approach is, this returns all the documents matching all three conditions. Any way can get the expected result through ES?


Solution

  • The current version of Elasticsearch (8.17) does not offer a solution for this complication. A workaround is to perform a msearch and handle it on the server side.