How to return results where a field starts with a specific letter or letters in Elasticsearch?
Asked Answered
K

1

6

I have some data like

"last_name": "AA-WEST"
"last_name": "VANDER AA"
"last_name": "ARENDES-AA"

And I'm trying to only get names that start with a, i.e. AA-WEST and ARENDES-AA

I've tried

"match": {
    "last_name": {
        "query": "a",
        "operator": "and"
    }
}

and

"prefix": {
    "last_name": { "value" : "a" }
}

and

"match_phrase_prefix": {
    "last_name.keyword": {
        "query": "a"
    }
}

All of these will return all names, not only that really start with a

Any ideas?

Knowhow answered 14/12, 2017 at 16:44 Comment(2)
Do you have any mappings predefined for your index ?Gossipmonger
it's just a text field. I have last_name.keyword and last_name for analyzed vs not analyzed. but running anything on last_name.keyword doesn't return any resultsKnowhow
G
4

So the reason why you're getting all the results is because it's a text field and VANDER AA will be transformed into two tokens. You can try:

POST http://{esUri}/_analyze HTTP/1.1
Content-type: application/json

{
   "tokenizer": "standard",
   "text":      "VANDER AA"
}

To avoid this you can define your type as a keyword, and then use

{ 
    "query": {
        "prefix" : { "last_name" : "A" }
    }
}

But I guess it's not what you're looking for because you want your query to be case-insensitive. To achieve that you should define normalizer for your field which will be automatically transforming your data to lowercase before indexing. You should start with defining your index

PUT http://{esAddress}/indexname HTTP/1.1
{
  "settings": {      
    "analysis": {
      "normalizer": {
        "lowercase_normalizer": {
          "type": "custom",
          "char_filter": [],
          "filter": ["lowercase"]
        }
      }     
    }
  },
  "mappings": {
    "yourtype": {
      "properties": {
        "last_name": {
          "type": "keyword",
          "doc_values": true,
          "normalizer": "lowercase_normalizer"
        }
      }
    }
  }
}

Then prefix query will give you exactly two results:

{ 
    "query": {
        "prefix" : { "last_name" : "a" }
    }
}
Gossipmonger answered 14/12, 2017 at 17:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.