Exact matches with ElasticSearch (at query time)

elasticsearch, java

Solution

Index the field you perform a term filter on as not_analyzed. For example, you can index the "country" field as a multi_field, with one of the sub-fields not_analyzed:

        "country": {
            "type": "multi_field",
            "fields": {
                "country": {"type": "string", "index": "analyzed"},
                "exact": {"type": "string","index": "not_analyzed"}
            }
        }

Additionally, you could do the same with the "title" field in order to perform a term query:

        "title": {
            "type": "multi_field",
            "fields": {
                "title": {"type": "string", "index": "analyzed"},
                "exact": {"type": "string","index": "not_analyzed"}
            }
        }

Then at query time, if you want a title with the exact term "Berlin" filtered by the exact term "DE", use a term query and term filter with the not_analyzed fields:

SearchResponse response = client.prepareSearch("locations")
                .setQuery(QueryBuilders.termQuery("title.exact", "Berlin"))
                .setFilter(FilterBuilders.termFilter("country.exact", "DE"))
                .execute()
                .actionGet();

Note that term filters and term queries require not_analyzed fields to work (i.e., to return exact matches).

Problem

I have a locations index, which has lots of location names and their respective countries. I then want to know whether we have locations with title "Berlin" in the country with country code "DE". Here's my Java code attempt: ``` SearchResponse response = client.prepareSearch("locations") .setQuery(QueryBuilders.matchQuery("title", "Berlin")) .setFilter(FilterBuilders.termFilter("country", "DE")) .execute() .actionGet(); ``` But this gives me too many replies, e.g. results for "Zoo Berlin" and so on. I need exact matches. (But please note that I have other scenarios where this substring/text search matching is desired.) Is there a way to decide at querying time, rather than at indexing time which behaviour (exact vs. analyzed text) one wants?

Original source

Related problems