How to perform full text search on number fields in ElasticSearch?
I suggest that you use the ngram tokenizer for that purpose.
Here is a code sample of what you might need. You would want to first set the analyzer settings with the tokenizer you wish to use.
curl -XPUT localhost:9200/test?pretty=true -d '{ "settings":{ "analysis":{ "analyzer":{ "my_ngram_analyzer":{ "tokenizer":"my_ngram_tokenizer" } }, "tokenizer":{ "my_ngram_tokenizer":{ "type":"nGram", "token_chars":[ "letter", "digit" ] } } } }}'
More on Ngram Tokenizer here.
Then you should define the following mapping:
curl -XPUT localhost:9200/test/items/_mapping?pretty=true -d '{ "items":{ "properties":{ "accountId":{ "analyzer":"my_ngram_analyzer", "type":"string" }, "name":{ "type":"string" } } }}'
The reason 'accountId' is a 'string' is that the Ngram tokenizer doesn't work on numeric fields.
Now you can query your index :
curl -XGET localhost:9200/test/_search?pretty=true -d'{ "query": { "query_string": { "default_field": "accountId", "query": "4" } }}'
You can find here the bash script I used to test it.
NB: Of course this is just a demo on about how you can use the Ngram Tokenizer. I hope it will help
Create a multi-field, that will contain a number field and also a string for searching
PUT /test/items/_mapping{ "items" : { "properties" : { "accountId" : { "type" : "multi_field", "fields" : { "numeric" : { "type" : "integer", "index" : "not_analyzed" }, "text" : { "type" : "string", "index" : "analyzed" } } } } }}
Verify your mapping:
GET /test/items/_mapping
Output
{ "test": { "mappings": { "items": { "properties": { "accountId": { "type": "integer", "index": "no", "fields": { "numeric": { "type": "integer" }, "text": { "type": "string" } } } } } } }}
Put your data into elastic search.
Now you can do a search as string, but you will get result as number:
GET /test/items/_search{ "query": { "query_string": { "default_field": "accountId.text", "query": "*4*" } }}
Output
{ "took": 15, "timed_out": false, "_shards": { "total": 4, "successful": 4, "failed": 0 }, "hits": { "total": 2, "max_score": 1, "hits": [ { "_index": "test", "_type": "items", "_id": "3", "_score": 1, "_source": { "accountId": 234234, "name": "Daniel" } }, { "_index": "test", "_type": "items", "_id": "1", "_score": 1, "_source": { "accountId": 12341234, "name": "Bob" } } ] }}