Elastic Search Match_phrase not giving deterministic result - elasticsearch

I have defined mapping in following way.
PUT _template/name
"mappings": {
"_default_": {
"name": {
"type": "string",
"analyzer" : "synonyms_expand",
"index" : "analyzed",
"position_offset_gap": 100
},
}
}
I am executing following query
GET _search
{
"query": {
"bool": {
"should" : [{
"match_phrase": {
"petitioners.name": {
"query": "onkar kundargi "
}
}
}]
}
}
}
still it is giving result for only onkar. Not evaluting complete string for search. Can anybody help me ???

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

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

How to escape backslash in ElasticSerach query

I have the following field in ElasticSearch:
"type": "doc\doc1"
My goal is to select a special type, I tried:
GET /my_index/my_type/_search
{
"query":{
"bool":{
"must":{
"term":{
"type": "doc\\doc1"
}
}
}
}
}
but it does not works, I tried:
"type": "doc\\\\doc1"
"type": "\"doc\\\\doc1"\"
"type": "\"doc\\doc1"\"
but the query returns no results.
I tried with:
GET /my_index/my_type/_search
{
"query" : {
"query_string" : {
"query" : "doc\\doc1",
"analyzer": "keyword"
}
}
}
But it's the same output.
Any helps would be greatly appreciated
Thanks!
You need to escape backslash in your field value.
Then you can search the exact value with the keyword analyzer with term query or instead you can use match query with analyzed value:
PUT test
{
"settings": {
"number_of_shards": 1
},
"mappings": {
"type1": {
"properties": {
"field1": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
}
}
}
}
}
}
}
PUT test/type1/1
{
"field1" : "doc\\doc1"
}
POST test/_search?pretty
{
"query": {
"bool": {
"must": {
"term": {
"field1.raw": "doc\\doc1"
}
}
}
}
}
POST test/_search?pretty
{
"query": {
"bool": {
"must": {
"match": {
"field1": "doc\\doc1"
}
}
}
}
}

Elasticsearch partial matching of a number field

I'm trying to partially match a number field. In the query below, I'd like id (which is defined as a long) to match any document which starts with 419. (so 4191 should match, as should 419534 but not 123419)
{
"size": 20,
"from": 0,
"sort": [{
"customerName": "asc"
}],
"query": {
"bool": {
"must": [{
"bool": {
"should": [{
"term": {
"id": 419
}
}]
}
}]
}
}
}
Anyone got a neat solution to use in my query?
To avoid a egde ngram, you could declare a not analyzed text sub field in your id mapping :
"mappings": {
"default": {
"properties": {
"id": {
"type": "integer",
"fields": {
"prefixed": {
"type": "string",
"index": "not_analyzed"
}
}
},
...
}
}
}
and use a prefix query against that field:
"query": {
"prefix" : {
"id.prefixed" : { "value" : 419 }
}
}
in a string field you can use wildcard query:
{
"query" : {
"wildcard" : { "id" : "*419*" }
}
}

Term, nested documents and must_not query incompatible in ElasticSearch?

I have trouble combining term, must_not queries on nested documents.
Sense example can be found here : http://sense.qbox.io/gist/be436a1ffa01e4630a964f48b2d5b3a1ef5fa176
Here my mapping :
{
"mappings": {
"docs" : {
"properties": {
"tags" : {
"type": "nested",
"properties" : {
"type": {
"type": "string",
"index": "not_analyzed"
}
}
},
"label" : {
"type": "string"
}
}
}
}
}
with two documents in this index :
{
"tags" : [
{"type" : "POST"},
{"type" : "DELETE"}
],
"label" : "item 1"
},
{
"tags" : [
{"type" : "POST"}
],
"label" : "item 2"
}
When I query this index like this :
{
"query": {
"nested": {
"path": "tags",
"query": {
"bool": {
"must": {
"term": {
"tags.type": "DELETE"
}
}
}
}
}
}
}
I've got one hit (which is correct)
When I want to get documents WHICH DON'T CONTAIN the tag "DELETE", with this query :
{
"query": {
"nested": {
"path": "tags",
"query": {
"bool": {
"must_not": {
"term": {
"tags.type": "delete"
}
}
}
}
}
}
}
I've got 2 hits (which is incorrect).
This issue seems very close to this one (Elasticsearch array must and must_not) but it's not...
Can you give me some clues to resolve this issue ?
Thank you
Your original query would search in each individual nested object and eliminate the objects that don't match, but if there are some nested objects left, they do match with your query and so you get your results. This is because nested objects are indexed as a hidden separate document
Original code:
{
"query": {
"nested": {
"path": "tags",
"query": {
"bool": {
"must_not": {
"term": {
"tags.type": "delete"
}
}
}
}
}
}
}
The solution is then quite simple really, you should bring the bool query outside the nested documents. Now all the documents are discarded who have a nested object with the "DELETE" type. Just what you wanted!
The solution:
{
"query": {
"bool": {
"must_not": {
"nested": {
"path": "tags",
"query": {
"term": {
"tags.type": "DELETE"
}
}
}
}
}
}
}
NOTE: Your strings are "not analyzed" and you searched for "delete" instead of "DELETE". If you want to search case insensitive, make your strings analyzed
This should fix your problem: http://sense.qbox.io/gist/f4694f542bc76c29624b5b5c9b3ecdee36f7e3ea
Two most important things:
include_in_root on "tags.type". This will tell ES to index tag types as "doc.tags.types" : ['DELETE', 'POSTS'], so you can access an array of those values "flattened" on the root doc . This means you no longer need a nested query (see #2)
Drop the nested query.
{
"mappings": {
"docs" : {
"properties": {
"tags" : {
"type": "nested",
"properties" : {
"type": {
"type": "string",
"index": "not_analyzed"
}
},
"include_in_root": true
},
"label" : {
"type": "string"
}
}
}
}
}
{
"query": {
"bool": {
"must_not": {
"term": {
"tags.type": "DELETE"
}
}
}
}
}

Resources