Vinod Kolla
Vinod Kolla

Reputation: 324

Elastic search - search query to match any one value for a particular key

I am new to ES querying. I am try to get results based on a key that can match any value rather than one particular value. For example: key foo can be one among bar, baz. I tried this with arrays and should but ended up with wrong results or exception. What will be the correct syntax for OR case in ES. I am using ES 5.6.*

Upvotes: 0

Views: 6585

Answers (3)

Marc
Marc

Reputation: 14277

I have a simpler solution which avoids complex bool queries and uses the terms array:

    "query": {
        "terms": {
            "foo": [
                "bar",
                "baz"
            ]
        }
    }
        

Upvotes: 0

Xin
Xin

Reputation: 36510

You need use bool condition combined with should and match or match_phrase (You will like match_phrase as long as you know exact what you want to search)

GET local-signaler/_search
{
  "query": {
    "bool" : {
      "should" : [
        { "match_phrase" : { "foo" : "bar" } },
        { "match_phrase" : { "foo" : "baz" } }
      ],
      "minimum_should_match" : 1
    }
  }
}

Upvotes: 1

Miek
Miek

Reputation: 1228

There are a lot of ways you could do this.

Depending upon the analyzer you're using, you could very much do it like this:

GET /test/_search
{
  "query": {
    "match": {
      "foo": "bar, baz"
    }
  }
}

Demonstrating what it analyzes to (by default in 5.6)

GET /test/_analyze
{
  "field": "foo",
  "text": [
    "bar, baz"
  ]
}

Outputting these tokens:

{
  "tokens": [
    {
      "token": "bar",
      "start_offset": 0,
      "end_offset": 3,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "baz",
      "start_offset": 5,
      "end_offset": 8,
      "type": "<ALPHANUM>",
      "position": 1
    }
  ]
}

In the above example, using "bar, baz" or "bar baz" would be equivalent to search both "bar" AND "baz".

You can also group them in queries like this:

GET /test/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "foo": "bar"
          }
        },
        {
          "match": {
            "foo": "baz"
          }
        }
      ]
    }
  }
}

The above would give you a scored query, requiring a match for both bar and baz in the queried documents.

You could also replace "must" with "filter", "should", or "must_not". "filter" would be unscored, should would switch you from an ANDing query to an ORing query (and you can also specify the minimum amounts of OR), or inverting the query with the "must_not"

Bool query

There are more ways than just this, but this should get you started on the right track.

A "should" example requiring a hit only one of the two terms, since that was your original question:

GET /test/_search
{
  "query": {
    "bool": {
      "minimum_should_match": 1, 
      "should": [
        {
          "match": {
            "foo": "bar"
          }
        },
        {
          "match": {
            "foo": "baz"
          }
        }
      ]
    }
  }
}

Upvotes: 1

Related Questions