Elasticsearch Full Text or Exact Value search


(sreeram) #1

Hi,

Below is my use case,

put /twitter/Company/1
{
"manufacturer": "ABC Technologies"
}

put /twitter/Company/2
{
"manufacturer": "DEF Technologies"
}

put /twitter/Company/3
{
"manufacturer": "Technologies"
}

put /twitter/Company/4
{
"manufacturer": "ABC DEF"
}

My document mappings are formed dynamically.

Now when I search,

GET /twitter/Company/_search
{
"query": {
"match": {
"manufacturer": "Technologies"
}
}
}

I get a response as below,
"manufacturer": "ABC Technologies"
"manufacturer": "DEF Technologies"
"manufacturer": "Technologies"

But my requirement is to fetch only,
"manufacturer": "Technologies"

If I'm not wrong, this Elasticsearch's behavior due to inverted indexing & standard analyzer.

I tried setting "keyword" analyzer for all string fields in dynamic_template as below,
PUT twitter
{
"mappings": {
"default": {
"dynamic_templates": [
{
"string_analyzer": {
"match_mapping_type": "string",
"match": "*",
"mapping": {
"type": "string",
"analyzer": "keyword"
}
}
}
]
}
}
}

It's working fine :slight_smile:

Questions:

  1. What are cons of using "keyword" analyzer (90% of my fields are string type and I can't pre-define my fields as my use case is dynamic json structure) ?
  2. Is there any better way to achieve my requirement?

Regards,
Sreeram


(Yeikel) #2

Take a look at this document : https://www.elastic.co/guide/en/elasticsearch/guide/current/aggregations-and-analysis.html

Your field needs to be "not analyzed"


(bashar) #3

try the below mapping it should work with you, the query you should use after you apply the new mapping is:
GET masterdatafinal/_search
{
"query": {
"match": {
"company.raw": "Technologies"
}
}
}
just keep in your mind 2 things,
1- this query will be case senstive
2- you should reindex your data to get result.

PUT twitter/_mapping/doc
{
"properties": {
"company": {
"type": "string",
"analyzer": "english",
"fields": {
"raw": {
"type": "string",
"index": "not_analyzed"
} } }}}


(system) #4