Search code examples
elasticsearchtokenphrasebooleanqueryelasticsearch-analyzers

How can we make few tokens to be phrase in elastic search query


I want to search part of query to be considered as phrase .For e.g. I want to search "Can you show me documents for Hospitality and Airline Industry" Here I want Airline Industry to be considered as phrase.I dont find any such settings in multi_match . Even when we try to use multi_match query using "Can you show me documents for Hospitality and \"Airline Industry\"" .Default analyser breaks it into separate tokens.I dont want to change settings of my analyser.Also I have found that we can do this in simple_query_string but that has consequences that we can not apply filter option as we have in multi_match boolean query because I want to apply filter on certain feilds as well.

search_text="Can you show me documents for Hospitality and Airline Industry" Now I Want to pass Airline Industry as a phrase to search my indexed document against 2 fields. okay so say I have existing code like this.

If filter:
qry={
    “query":{
        “bool”:{
            “must”:{
                "multi_match":{
                "query":search_text,
                "type":"best_fields",
                "fields":["TITLE1","TEXT"],
                "tie_breaker":0.3,
                }
            },
            “filter”:{“terms”:{“GRP_CD”:[“1234”,”5678”]     }
    }
    }

else:
qry={

    "query":{
        "multi_match":{
        "query":search_text',
        "type":"best_fields",
        "fields":["TITLE1",TEXT"],
        "tie_breaker":0.3
        }
    }
}

'But then I have realised this code is not handling Airline Industry as a phrase even though I am passing search string like this "Can you show me documents for Hospitality and \"Airline Industry\""

As per elastic search document I came to know there is this query which might handle this

qry={"query":{
"simple_query_string":{
"query":"Can you show me documents for Hospitality and \"Airline Industry\"",
"fields":["TITLE1","TEXT"] }
} }

But now my issue is what if user want to apply filter..with filter query as above I can not pass phrase and boolean query is not possible with simple_query_string'


Solution

  • You can always combine queries using boolean query. Lets understand this case by case. Before going to the cases I would like to clarify one thing which is about filter. The filter clause of boolean query behave just like a must clause but the difference is that any query (even another boolean query with a must/should clause(s)) inside filter clause have filter context. Filter context means, that part of query will not be considered for score calculation.

    Now lets move on to cases:

    Case 1: Only query and no filters.

    {
      "query": {
        "bool": {
          "must": [
            {
              "simple_query_string": {
                "query": "Can you show me documents for Hospitality and \"Airline Industry\"",
                "fields": [
                  "TITLE1",
                  "TEXT"
                ]
              }
            }
          ]
        }
      }
    }
    

    Notice that the query is same as specified by you in the question. All I have done here is that I wrapped it in a bool query. This doesn't make any logical change to the query but doing so will make it easier to add queries to filter clause programmatically.

    Case 2: Phrase query with filter.

    {
      "query": {
        "bool": {
          "must": [
            {
              "simple_query_string": {
                "query": "Can you show me documents for Hospitality and \"Airline Industry\"",
                "fields": [
                  "TITLE1",
                  "TEXT"
                ]
              }
            }
          ],
          "filter": [
            {
              "terms": {
                "GRP_CD": [
                  "1234",
                  "5678"
                ]
              }
            }
          ]
        }
      }
    }
    

    This way you can combine query(query context) with the filters.