Search using "OR" condition on keyword field that contains spaces

My data "keywords" contain spaces. So "X AAA" is one "keyword". And "B AAA" is another keyword. My data will only have one of these in the actual field. So the data field will never look like a combination of the two "X AAA B AAA". There will always be just one "keyword" in the field.

Here is a sample data set of 6 rows for the field:
X AAA
Y AAA
Z AAA
X BBB
Y BBB
Z BBB

My mapping looks like this for the field

"mappings" : {
  "properties" : {
    "MYKEYWORDFIELD" : {
      "type" : "keyword"
    },
    ...

When I query the MYKEYWORDFIELD for only part of the "keyword" such as "AAA" I don't get any results. This is what I want. Thus my understanding is that the field is being treated as the entire contents of the field is one keyword. Am I understanding this correctly?

Also, I want to query MYKEYWORDFIELD for "X AAA" OR "X BBB" in a single query. Is it possible to do so? If so, how would I do so?

With a Bool query which contains 2 should clauses?

Thanks for the response... but it needs to be a "must". I don't want to potentially get results for others rows in my query.

I could make two different queries and combine them. I'd just hope there's a way to do it in one query.

The title of your post says that you want a OR condition. But I misunderstood it most likely.

Could you provide a full recreation script as described in About the Elasticsearch category. It will help to better understand what you are doing. Please, try to keep the example as simple as possible.

A full reproduction script will help readers to understand, reproduce and if needed fix your problem. It will also most likely help to get a faster answer.

Thanks again for the response.

DELETE mytestindex
PUT mytestindex
{
  "mappings": {
    "properties": {
      "MYKEYWORDFIELD": {
        "type": "keyword"
      }
    }
  }
}
PUT mytestindex/_doc/1
{
  "MYKEYWORDFIELD": "X AAA",
  "OTHERFIELD":"1"
}
PUT mytestindex/_doc/2
{
  "MYKEYWORDFIELD": "Y AAA",
  "OTHERFIELD":"1"
}
PUT mytestindex/_doc/3
{
  "MYKEYWORDFIELD": "Z AAA",
  "OTHERFIELD":"1"
}
PUT mytestindex/_doc/4
{
  "MYKEYWORDFIELD": "X BBB",
  "OTHERFIELD":"1"
}
PUT mytestindex/_doc/5
{
  "MYKEYWORDFIELD": "Y BBB",
  "OTHERFIELD":"1"
}
PUT mytestindex/_doc/6
{
  "MYKEYWORDFIELD": "Z BBB",
  "OTHERFIELD":"1"
}

The query below returns all the documents above. I only want results with "X AAA" or "Y AAA" in the MYKEYWORDFIELD field in the results. (I need the "OTHERFIELD" match, because my query is more complex than just the MYKEYWORDFIELD and including it mimics my other query parameters at a very basic level)

GET /mytestindex/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "OTHERFIELD": {
                "query":    "1"
            }         
          }   
        }
      ],
      "should": [
        {
          "match": {
            "MYKEYWORDFIELD": {
                "query":    "X AAA"
            }         
          }   
        },
        {
          "match": {
            "MYKEYWORDFIELD": {
                "query":    "Y AAA"
            }         
          }   
        }
      ]
    }
  }
}

Change

 "match": {
            "MYKEYWORDFIELD": {
                "query":    "X AAA"
            }         
          }   

to

 "wildcard": {
            "MYKEYWORDFIELD.keyword": {
                "query":    "* AAA"
            }         
          }

Assuming your field is text. If it's already keyword, then just remove the ".keyword".

@linkerc - Thanks for the idea. I believe your solution would also return "Z AAA" which I do not want in my results. I only want results with "X AAA" or "Y AAA" in the MYKEYWORDFIELD field in the results.

Also, I would want to be able to query for "X AAA" OR "Y BBB", which I don't believe your wildcard solution would handle.

I discovered you could nest "bool". So I tried the code below and it looks like nesting a bool "should" within a "must" is a working solution.

I don't fully get why it works. You'd think the "should" block would still return results like "X BBB" (but just with a lower score) as it would if it were not nested (my code sample above), but it doesn't seem to do that.

Regardless, from my testing, this appears to be my solution!

GET /mytestindex/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "OTHERFIELD": {
                "query":    "1"
            }         
          }   
        },        
        {
          "bool": {
            "should": [
              {
                "match": {
                  "MYKEYWORDFIELD": {
                      "query":    "X AAA"
                  }         
                }   
              },
              {
                "match": {
                  "MYKEYWORDFIELD": {
                      "query":    "Y AAA"
                  }         
                }   
              }
            ]
          }          
        }
      ]
    }
  }
}

What about:

GET /mytestindex/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "bool": {
            "must": [
              {
                "match": {
                  "OTHERFIELD": {
                    "query": "1"
                  }
                }
              },
              {
                "match": {
                  "MYKEYWORDFIELD": {
                    "query": "X AAA"
                  }
                }
              }
            ]
          }
        },
        {
          "bool": {
            "must": [
              {
                "match": {
                  "OTHERFIELD": {
                    "query": "1"
                  }
                }
              },
              {
                "match": {
                  "MYKEYWORDFIELD": {
                    "query": "Y AAA"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.