Elasticsearch query on zip_code failed - elasticsearch

I have a strange behavior on elasticsearch that I cant explain.
When I do :
POST /ad_search/_search
{
"query": {
"match": {
"city_code": "2A247"
}
}
}
I have multiple result. But when I do (This code is generated by a librairies) :
POST /ad_search/_search
{
"from":0,
"query": {
"bool": {
"must":[
{"term":{"city_code":"2A247"}}
]
}
}
}
I have no result.
When I search on all other zip_code with only numbers like 71459. The both query are working well and give me the same result.
I was thinking of a mapping problems but it seems ok :
GET /ad_search/_mapping
{
"ad_search" : {
"mappings" : {
"properties" : {
"city_code" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
Someone have any ideas to unlock me ?
Thank you

It's because city_code is of type text and thus analyzed, hence what is being indexed is 2a247 (lowercase).
So you can either query city_code.keyword with a term query, which does an exact match
POST /ad_search/_search
{
"from":0,
"query": {
"bool": {
"must":[
{"term":{"city_code.keyword":"2A247"}}
]
}
}
}
Or with a match query on the city_code field:
POST /ad_search/_search
{
"from":0,
"query": {
"bool": {
"must":[
{"match":{"city_code":"2A247"}}
]
}
}
}

Related

exact match with Elasticsearch query_string

I'm able to perform exact match query by following Elasticsearch boolean query:
GET my_index/_search
{
"query": {
"bool": {
"filter": [
{
"term": {
"some_field.keyword": "some value"
}
}
]
}
}
}
some_field is indexed as default string type:
"some_field" : {
"properties" : {
"value" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
For some reason, I can only use Elasticsearch query_string. This means, I need equivalent query in Lucene syntax.
You can do the same way in query_string query with keyword variation of the field.
{
"query": {
"query_string": {
"query": "some value",
"default_field": "some_field.value.keyword"
}
}
}

Multi-query match_phrase_prefix elasticsearch

I would like to query 2 different prefixes for the same field. The code below works exactly how I would like it to when working with on field:
GET /logstash-*/_search
{
"query": {
"match_phrase_prefix" : {
"type" : {
"query" : "job-source"
}
}
}
}
I could not find in the docs how to do this with two queries (I found how to search in multiple fields). I have tried a boolean should and the snippet below but both are not giving me the results I am looking for.
GET /logstash-*/_search
{
"query": {
"match_phrase_prefix" : {
"type" : {
"query" : ["job-source","job-find"]
}
}
}
}
How do I query for only documents that have type:job-source or type:job-find as the prefix?
Thank you in advance,
You can combine two match_phrase_prefix queries using should and set minimum_should_match to 1.
Sample Query:
{
"query":
{
"bool":
{
"should": [
{
"match_phrase_prefix":
{
"type": "job-source"
}
},
{
"match_phrase_prefix":
{
"type": "job-find"
}
}],
"minimum_should_match": 1
}
}
}

Elasticsearch: How to get an exact match in a nested field

The mapping contains nested fields which shouldn't be analyzed (not sure if the 'not_analyzed' value is accurate). Is it possible to do an exact match on a nested field? In the query below the "metadata.value": "2014.NWJSD.47" still gets analyzed. Elasticsearch breaks up the string into several terms ("2014", "NWJSD", "47"). I tried to use "term" instead of "match" but this didn't return any result.
"mappings" : {
"metadata" : {
"type" : "nested",
"properties" : {
"name" : {
"type" : "text",
"index" : "not_analyzed"
},
"value" : {
"type" : "text",
"index" : "not_analyzed"
}
}
}
}
The Query:
"query": {
"bool": {
"must": [
{
"nested": {
"path": "metadata",
"query": {
"bool": {
"must": [
{
"match": {
"metadata.name": "number"
}
},
{
"match": {
"metadata.value": "2014.NWJSD.47"
}
}
]
}
}
}
}
]
}
}
Try to use keyword instead of text in your mapping like:
{
"mappings": {
"your_type_name": {
"properties": {
"metadata" : {
"type" : "nested",
"properties" : {
"name" : {
"type" : "keyword"
},
"value" : {
"type" :"keyword"
}
}
}
}
}
}
}
These fields won't be analyzed. Then you should reindex your data and to query your data you should replace match (which is analyzed query) with term.
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "metadata",
"query": {
"bool": {
"must": [
{
"term": {
"metadata.name": "number"
}
},
{
"term": {
"metadata.value": "2014.NWJSD.47"
}
}
]
}
}
}
}
]
}
}
}
I think you are looking for a query string query.
You can freely disable "analyze" option for that field in mapping option and reindex everything again but you could also check this query out:
as written here:
GET /_search
{
"query": {
"query_string" : {
"query" : "your string"
}
}
}

Querying a nested array in Elasticsearch

I have the following data index in Elasticsearch with the following syntax:
PUT /try1
{
"mappings" : {
"product" : {
"properties" : {
"name": { "type" : "text" },
"categories": {
"type": "nested",
"properties": {
"range":{"type":"text"}
}
}
}
}
}
}
The range type has an array of words:["high","medium","low"]
I need to access the range element inside the nested category. I tried using the following syntax:
GET /try1/product/_search
{
"query": {
"nested" : {
"path" : "categories",
"query" : {
"bool" : {
"must" : [
{ "match" : {"categories.range": "low"} }
]
}
}
}
}
}
However, I am getting an error with the message:
"reason": """failed to create query:...
Can someone please offer a solution to this?
#KGB can you try to make your query slightly differently like this:
{
"query": {
"bool": {
"must": [
{
"match": {
"categories.range": "low"
}
}
]
}
}
}
{
"query": {
"nested" : {
"path" : "categories",
"query" : {
"bool" : {
"must" : [
{ categories.range": "low"}
]
}
}
}
}
}
This worked perfectly

ElasticSearch - Single match to multiple

Note that I am a complete newbie with ElasticSearch and I'm on a time crunch. I've got the query below:
{
    "query": {
        "filtered": {
            "query": {
                "match": {
                    "state": "VA"
                }
            },
            "filter": {
                "and": [
                    {
                        "bool": {
                            "must": [
                                {
                                    "match": {
                                        "status": "Active"
                                    }
                                }
                            ]
                        }
                    }
                ]
            }
        }
    },
    "sort": [
        "dom"
    ],
    "size": 1
}
At the moment, the codebase only supports searching for items with one state in particular. I am trying to modify it to support a list of possible state values. Now, I've seen where one can use should and terms but the results for both are empty data sets.
I've tried looking this up but examples I've seen either don't work, or have very poorly explained (if at all) solutions, or depend on reading and absorbing pages of documentation (for which I simply do not have the time). How would I modify the top query to search for multiple values?
Update
Running the following:
curl -XGET localhost:9200/listings/_mapping/listing/field/state?pretty
I have acquired this mapping:
{
"listings" : {
"mappings" : {
"listing" : {
"state" : {
"full_name" : "state",
"mapping" : {
"state" : {
"type" : "string"
}
}
}
}
}
}
}
Update 2
I've updated the mapping to set it to not_analyzed and enabled the store option. Data has been reimported. The new request looks like this:
{
"query":{
"filtered":{
"filter":{
"and":[
{
"bool":{
"should":[
{
"terms":{
"state":["VA","MD"]
}
}
]
}
},{
"bool":{
"must":[
{
"match":{
"status":"Active"
}
}
]
}
}
]
}
}
},
"sort":["dom"],
"size":1
}
Did you try replacing the inner "query" for your "reverse engineered" query?
Something like this:
{
"query": {
"filtered": {
"query": {
"bool": {
"should": [
{
"match": {
"state": "VA"
}
},
{
"match": {
"state": "MD"
}
}
]
}
},
"filter": {
"and": [
{
"bool": {
"must": [
{
"match": {
"status": "Active"
}
}
]
}
}
]
}
}
},
"sort": [
"dom"
],
"size": 1
}
By the way, this query is a bit messy. You could reestrucuture it combining the "must" and "should" clauses under a single "bool". You could then discard the "filtered" query and use the single "bool" immediately under root "query" tag, or discard "query" section of "filtered" and use only the "filter" part.

Resources