parth
parth

Reputation: 674

Does Elasticsearch support AND query for multiple values?

ElasticSearch v: 5.3

I've one items array store in elastic search.

userId: "123"
items: [
  {
    "range": {
      "from": 10,
      "to": 30
    },
    "id": "1"
  },
  {
    "range": {
      "from": 20,
      "to": 100
    },
    "id": "2"
  },
  {
    "range": {
      "from": 5,
      "to": 90
    },
    "id": "3"
  },
]

This is only single record. Consider this as multiple records which contains items key. Now i want to perform search query with id and it's respected range. So my current query is like this

GET product/item/_search{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "items.id": "1"
          }
        },
        {
          "range": {
            "items.range.from": {
              "gte": 20,
              "lte": 30
            }
          }
        },
        {
          "range": {
            "items.range.to": {
              "gte": 20,
              "lte": 30
            }
          }
        },

      ]
    }
  }
}

Currently this will perform a search query which has id=1 and range values from >= 20 and to <= 30. So it will return all the records containing id=2 and also which has range between 20 to 30. So even if in other records if id=1 is not present it will search for range values an will return records if range matches.

Instead of this i want to search for records which has id=1 and that id's value should between 20 to 30. So My question is does elastic search supports this kind of in between AND query?

Upvotes: 0

Views: 771

Answers (1)

Val
Val

Reputation: 217474

You need your items field to be nested in your mapping, like this:

PUT product
{
  "mappings": {
    "item": {
      "properties": {
        "itemId": {
          "type": "long"
        },
        "items": {
          "type": "nested",
          "properties": {
            "id": {
              "type": "long"
            },
            "range": {
              "properties": {
                "from": {
                  "type": "long"
                },
                "to": {
                  "type": "long"
                }
              }
            }
          }
        }
      }
    }
  }
}

Then you'll be able to query like this:

GET product/item/_search
{
  "query": {
    "nested": {
      "path": "items",
      "query": {
        "bool": {
          "filter": [
            {
              "term": {
                "items.id": "1"
              }
            },
            {
              "range": {
                "items.range.from": {
                  "gte": 20,
                  "lte": 30
                }
              }
            },
            {
              "range": {
                "items.range.to": {
                  "gte": 20,
                  "lte": 30
                }
              }
            }
          ]
        }
      }
    }
  }
}

PS: I suggest that you look at the integer_range data type instead of your range.from/to object. Just my two cents

Upvotes: 1

Related Questions