Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating an ElasticSearch query to search all fields and use partial matching at the same time

Separately, I have partial search working and I can search all fields. But I'm unable use partial matching on a search that maps all fields.

This returns my name when I use partial matching:

GET /_search?pretty=true
{ 
    "query": {
        "match": {
            "FullName": "andon"
        }
    }
}

This search runs on all fields, but doesn't do partial matching (0 hits):

GET /_search?pretty=true
{
    "query": {
        "match": {
           "_all": "andon"
        }
    }
}

What do I need to do to combine partial matching with a search on all fields & types? I have many fields and types so I'm hoping to avoid having to specify them all manually.

If it makes any difference, I'm inserting my data from a River that connects to SQL.

EDIT: I now have the _all field in my mapping. It appears to make no difference.

PUT /contact/
{
    "settings" : {
        "index" : {
            "analysis" : {
                "analyzer" : {
                    "my_ngram_analyzer" : {
                        "tokenizer" : "my_ngram_tokenizer"
                    }
                },
                "tokenizer" : {
                    "my_ngram_tokenizer" : {
                        "type" : "nGram",
                        "min_gram" : "1",
                        "max_gram" : "10"
                    }
                }
            }
        }
    },
    "mappings": {
        "_default_": {
            "_all" : {"enabled" : true},
            "properties" : {
                "Description":{"type":"string","store":"yes", "index_analyzer": "my_ngram_analyzer"},
                "OfficePhone":{"type":"string","store":"yes"},
                "Email":{"type":"string","store":"yes", "index_analyzer": "my_ngram_analyzer"},
                "FullName":{"type":"string","store":"yes", "index_analyzer": "my_ngram_analyzer"},
                "ReportsTo":{"type":"string","store":"yes"},
                "Department":{"type":"string","store":"yes", "index_analyzer": "my_ngram_analyzer"},
                "Title":{"type":"string","store":"yes", "index_analyzer": "my_ngram_analyzer"}
            }
        }
    }
}
like image 589
Brandon Avatar asked Feb 12 '14 15:02

Brandon


People also ask

How do I search all fields in Elasticsearch?

Either the query_string query or the match query would be what you're looking for. query_string will use the special _all field if none is specified in default_field , so that would work out well. And with match you can just specify the _all as well.

How does match query work in Elasticsearch?

The match query analyzes any provided text before performing a search. This means the match query can search text fields for analyzed tokens rather than an exact term. (Optional, string) Analyzer used to convert the text in the query value into tokens. Defaults to the index-time analyzer mapped for the <field> .

What is the difference between term and match query in Elasticsearch?

As the match_phrase queries, the input is analyzed according to the analyzer set on the queried field. Unlike the match_phrase , the terms obtained after analysis don't have to be in the same order, unless the user has used quotes around the input.

What is _source in Elasticsearch query?

The _source field contains the original JSON document body that was passed at index time. The _source field itself is not indexed (and thus is not searchable), but it is stored so that it can be returned when executing fetch requests, like get or search.


2 Answers

The _all-field works by taking the text for all fields, pass them through the analyzer for _all (which is standard unless overridden), then index the resulting terms.

It does not take whatever terms are made by the analyzers for the other fields and shove them all into the same field.

Thus, you'd have to override the _all-field to use your custom analyzer.

But! I don't think you'd really want to do that. You'll get a much larger index. Having _all is convenient at times, but it's usually better to control what fields are searched at search time.

So instead of doing a match on _all, you probably want to be using multi_match, specifying your fields. You can also consider copy_to if you're on 1.0.

like image 161
Alex Brasetvik Avatar answered Sep 29 '22 10:09

Alex Brasetvik


I tried searching with wildcard characters(%2A) and was able to do partial searches

ex => ?q=chew%2A&size=100

like image 41
Manish Hittalmani Avatar answered Sep 29 '22 12:09

Manish Hittalmani