How to perform full text search on number fields in ElasticSearch? How to perform full text search on number fields in ElasticSearch? elasticsearch elasticsearch

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"            }         }      ]   }}