9
votes

I am looking for ElasticSearch query which will provide exact match on string having spaces in it.

for example - I want to search for a word like 'XYZ Company Solutions'. I tried querystring query but it gives me all the records irrespective of search result. Also i read on the post and found that we have to add some mappings for the field. I tried 'Not_Analyzed' analyzer on the field but still it does not worked.

If anyone have complete example or steps then can you please share with me?

Thanks in advance.

Thanks, Sameer

2

2 Answers

5
votes

Since you didn't post your code it's hard to tell what's wrong, but "index": "not_analyzed" in your mapping is the right way to handle this.

Here is a simple working example. First I create a mapping that uses "index": "not_analyzed":

PUT /test_index
{
    "mappings": {
        "doc": {
            "properties": {
                "name":{
                    "type": "string",
                    "index": "not_analyzed"
                }
            }
        }
    }
}

Then add a couple of documents for testing

POST /test_index/doc/_bulk
{"index":{"_id":1}}
{"name":"XYZ Company Solutions"}
{"index":{"_id":2}}
{"name":"Another Company"}

Now I can get the document I want with a simple term query:

POST /test_index/doc/_search
{
    "query": {
        "term": {
           "name": {
              "value": "XYZ Company Solutions"
           }
        }
    }
}
...
{
   "took": 1,
   "timed_out": false,
   "_shards": {
      "total": 1,
      "successful": 1,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 1,
      "hits": [
         {
            "_index": "test_index",
            "_type": "doc",
            "_id": "1",
            "_score": 1,
            "_source": {
               "name": "XYZ Company Solutions"
            }
         }
      ]
   }
}

A term filter or even match query would also work in this case.

Here is the code I used to test it:

http://sense.qbox.io/gist/90fcc7f7a88d58f098c50d5aaf0315fdf06e9e9a

0
votes
PUT /index_1
{   
  "settings": {
    "analysis": {
      "normalizer": {
        "lowercase_normalizer": { "type": "custom", "char_filter": [],           "filter": ["lowercase"]}
      }
    }
  },
  "mappings": {
     "doc_type": {
            "properties": {
                "name":{"type": "keyword", "normalizer": "lowercase_normalizer"}
            }
     }
  }
}

I used the above the setting and mapping to define the index. Then pushed a few values into the database

POST index_1/doc_type/1
{
  "name" : "a b c"
}

POST index_1/doc_type/1
{
  "name" : "a c"
}

POST index_1/doc_type/1
{
  "name" : "a b"
}

Now if we search for individual letters in the name field of above index we get nothing in return

GET index_1/doc_type/_search
{
  "query" : 
    {"match": {"name": "A"}}
}

GET index_1/doc_type/_search
{
  "query" : 
    {"match": {"name": "b"}}
}

but if we search for

GET index_1/doc_type/_search
{
  "query" : 
    {"match": {"name": "A B C"}}
}

we will get the match

This helps searching complete keyword while avoiding case-senstivity