3
votes

I have an indexed field 'properties.language' with the value 'en sv'. This field has a multi_field mapping that consists of two fields, one analyzed (name 'language'), and one that is not_analyzed (name '_exact').

How do I issue a single search query without having to query both 'properties.language' and 'properties.language._exact'?

Edit:

Here is my configuration:

Indexed data:

{
    "_index": "51ded0be98035",
    "_type": "user",
    "_id": "WUzwcwhTRbKur7J5ZY_hgA",
    "_version": 1,
    "_score": 1,
    "_source": {
        "properties": {
            "language":"en sv"
        }
    }
}

Mapping for type 'user':

{
    "user": {
        "properties": {
            "properties": {
                "properties": {
                    "language": {
                        "type": "multi_field",
                        "fields": {
                            "language": {
                                "type": "string",
                                "analyzer": "standard",
                                "index": "analyzed"
                            },
                            "_exact": {
                                "type": "string",
                                "index": "not_analyzed"
                            }
                        }
                    }
                }
            }
        }
    }
}

Search query:

{
    "query": {
        "filtered": {
            "query": {
                "match_all": {}
            },
            "filter": {
                "bool": {
                    "must": [{
                        "or": [{
                            "term": {
                                "properties.language": "en sv"
                            }
                        }, {
                            "term": {
                                "properties.language._exact": "en sv"
                            }
                        }]
                    }]
                }
            }
        }
    }
}
1
Can you paste your settings (analyzers), mappings and queries? It's difficult to tell what kind of results you're looking to achieve only by description.James Addison
I have updated the question.Robin Orheden
So you always want to match on exactly en sv then? If so, then you only need to do a must match on your _exact field. Although, I'm guessing that's not the issue you're having... I'm confused what you're actually trying to accomplish in your query.James Addison
No, I would like to be able to match on both the analyzed and the exact text. But I don't want to specify both in the query. I.e. the following queries should match: ['en sv', 'sv', 'en']. I would also like a wildcard search on the exact text, but that is a different question...Robin Orheden
I'm struggling to see why you need to have exact matching for anything (except the wildcard), unless you have not given us all your requirements. If you just use a bog-standard mapping and send 'ev sv' to it. the queries ['en sv', 'sv', 'en'] will all match. Then use the not_analyzed version for wildcard stuff. Though there are much faster ways to do wildcard-like search.ramseykhalaf

1 Answers

3
votes

Consider indexing the language field using Elasticsearch builtin multi-valued fields (ie. arrays) instead: http://www.elasticsearch.org/guide/reference/mapping/array-type/. As you currently do, set index to not_analyzed.

When indexing your data, instead of a single value 'en sv', pass instead ['en', 'sv'], and ES will take care of the rest.

For querying, this gives you the ability to do the following to find items with both en and sv:

{
    "query": {
        "filtered": {
            "query": {
                "match_all": {}
            },
            "filter": {
                "bool": {
                    "must": [{
                        "term": {
                            "properties.language": "en"
                        }
                    }, {
                        "term": {
                            "properties.language": "sv"
                        }
                    }]
                }
            }
        }
    }
}

Or even better, find greater brevity/flexibility using the terms query/filter instead of term: http://www.elasticsearch.org/guide/reference/query-dsl/terms-query/