David
David

Reputation: 2423

Elasticsearch match certain fields exactly but not others

I am needing ElasticSearch to match certain fields exactly, currently using multi_match.

For example, a user types in long beach chiropractor.

I want long beach to match the city field exactly, and not return results for seal beach or glass beach.

At the same time chiropractor should also match chiropractic.

Here is the current query I am using:

"query": {
    "bool": {
        "should": [
            {
                "multi_match": {
                                "fields": [
                                    "title",
                                    "location_address_address_1.value",
                                    "location_address_city.value^2",
                                    "location_address_state.value",
                                    "specialty" // e.g. chiropractor
                                ],
                                "query": "chiropractor long beach",
                                "boost": 6,
                                "type": "cross_fields"
                }
            }
        ]
    }
},

Upvotes: 0

Views: 68

Answers (1)

Marko Vranjkovic
Marko Vranjkovic

Reputation: 6869

The right approach would be to separate term that is searched and location, and store location as keyword type. If that's not possible then you can use synonym tokenizer to store locations as single tokens, but this will require to have the list of all possible locations. e.g.

{
  "settings": {
    "analysis": {
      "filter": {
        "my_synonym_filter": {
          "type": "synonym",
          "synonyms": [
            "long beach=>long-beach"
          ]
        }
      },
      "analyzer": {
        "my_synonyms": {
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "my_synonym_filter"
          ]
        }
      }
    }
  }
}

Now if you call

POST /my_index/_analyze?analyzer=my_synonyms    
{
    "text": ["chiropractor long beach"]
}

the response is

{
    "tokens": [
        {
            "token": "chiropractor",
            "start_offset": 0,
            "end_offset": 12,
            "type": "<ALPHANUM>",
            "position": 0
        },
        {
            "token": "long-beach",
            "start_offset": 13,
            "end_offset": 23,
            "type": "SYNONYM",
            "position": 1
        }
    ]
}

Upvotes: 1

Related Questions