Search code examples
elasticsearchelasticsearch-6term-query

How to match one from many terms query?


Let's say I have a query language that parses "natural" language queries into elastic search queries.

Assuming we have the following query:

(type == "my-type" || device_id == "some-device-id") && id == "123456789"

How can I achieve this in elastic search?

I've tried with:

{
    "bool": {
        "filter": {
            "term": {
                "id": "123456789"
            }
        },
        "should": [
            {
                "term": {
                    "type": "my-type"
                }
            },
            {
                "term": {
                    "device_id": "some-device-id"
                }
            }
        ]
    }
}

but this is not what I want.

What am I doing wrong?

Mapping:

{
    "mappings": {
        "_doc": {
            "properties": {
                "accepted_at":  {
                    "type": "date",
                    "format": "strict_date_optional_time||date_time||epoch_millis"
                },
                "created_at":   {
                    "type": "date",
                    "format": "strict_date_optional_time||date_time||epoch_millis"
                },
                "device_id":    {"type": "keyword"},
                "id":       {"type": "keyword"},
                "location": {"type": "geo_point"},
                "message_id":   {"type": "keyword"},
                "type":     {"type": "keyword"}
            }
        }
    }
}

Solution

  • In elasticsearch you can think of && as must and || as should in bool query, so you can translate this query

    (type == "my-type" || device_id == "some-device-id") && id == "123456789"

    as

    must(should(type == "my-type"),(device_id == "some-device-id"), id == "123456789")

    which gives us this query when we want to convert it to elasticsearch DSL

    {
      "query": {
        "bool": {
          "must": [
            {
              "bool": {
                "should": [
                  {
                    "term": {
                      "type": {
                        "value": "my-type"
                      }
                    }
                  },
                  {
                    "term": {
                      "device_id": {
                        "value": "some-device-id"
                      }
                    }
                  }
                ]
              }
            },
            {
              "term": {
                "id": {
                  "value": "123456789"
                }
              }
            }
          ]
        }
      }
    }
    

    Hope that helps.