Elasticsearch nested object query_string - elasticsearch

I have question about query_string query in ElasticSearch. I want create fulltext search over all types and fields in index. Is query_string string performed against nested objects ? For example I have this mapping
{
"my_index": {
"mappings": {
"my_type": {
"properties": {
"group": {
"type": "string"
},
"user": {
"type": "nested",
"properties": {
"first": {
"type": "string"
},
"last": {
"type": "string"
}
}
}
}
}
}
}
}
And the query
GET /my_index/_search
{
"query": {
"query_string" : {
"query" : "paul"
}
}
}
So when I call the query, will ES search across all fields including nested or only in my_type object and for nested search I will have to use nested query ?

You cannot reference nested fields from a query_string at the root. i.e. this won't work:
{
"query": {
"query_string": {
"query": "myNestedObj.myTextField:food"
}
}
}
To search in specific nested fields, you must use the nested clause:
{
"query": {
"nested": {
"path": "myNestedObj",
"query": {
"query_string": {
"query": "myNestedObj.myTextField:food"
}
}
}
}
}
}
However, I've found that the pseudo-field "_all" does include nested fields, so this query would find documents containing 'food' in myNestedObj.myTextField (as well as anywhere else)
{
"query": {
"query_string": {
"query": "_all:food"
}
}
}

Try:
GET my_index/_search?q=paul

Related

Term query on nested fields returns no result in Elasticsearch

I have a nested type field in my mapping. When I use Term search query on my nested field no result is returned from Elasticsearch whereas when I change Term to Match query, it works fine and Elasticsearch returns expected result
here is my mapping, imagine I have only one nested field in my type mapping
{
"homing.estatefiles": {
"mappings": {
"estatefile": {
"properties": {
"DynamicFields": {
"type": "nested",
"properties": {
"Name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"ValueBool": {
"type": "boolean"
},
"ValueDateTime": {
"type": "date"
},
"ValueInt": {
"type": "long"
}
}
}
}
}
}
}
}
And here is my term query (which returns no result)
{
"from": 50,
"size": 50,
"query": {
"bool": {
"filter": [
{
"nested": {
"query": {
"bool": {
"must": [
{
"term": {
"DynamicFields.Name":{"value":"HasParking"}
}
},
{
"term": {
"DynamicFields.ValueBool": {
"value": true
}
}
}
]
}
},
"path": "DynamicFields"
}
}
]
}
}
}
And here is my query which returns expected result (by changing Term query to Match query)
{
"from": 50,
"size": 50,
"query": {
"bool": {
"filter": [
{
"nested": {
"query": {
"bool": {
"must": [
{
"match": {
"DynamicFields.Name":"HasParking"
}
},
{
"term": {
"DynamicFields.ValueBool": {
"value": true
}
}
}
]
}
},
"path": "DynamicFields"
}
}
]
}
}
}
This is happening because the capital letters with the analyzer of elastic.
When you are using term the elastic is looking for the exact value you gave.
up until now it sounds good, but before it tries to match the term, the value you gave go through an analyzer of elastic which manipulate your value.
For example in your case it also turn the HasParking to hasparking.
And than it will try to match it and of course will fail. They have a great explanation in the documentation in the "Why doesn’t the term query match my document" section. This analyzer not being activated on the value when you query using match and this why you get your result.

How do I query an Elasticsearch nested document within an inner object?

I'm trying to filter on a field within a nested document in an Elasticsearch query (ES 5.6.2). The nested document is itself a field within an inner object of the main document. The mapping looks like this:
{
"mappings": {
"container": {
"properties": {
"host": {
"properties": {
"tags_nested": {
"type": "nested",
"properties": {
"tag_key": {
"type": "keyword"
},
"tag_val": {
"type": "keyword"
}
}
}
}
}
}
}
}
}
I want to filter on host.tags_nested.tag_keys, but I can't figure out the right syntax to access the nested tags_nested document within the host inner object. I tried the following query, which doesn't return any results, when I know there are some that should match:
{
"query": {
"nested": {
"path": "host.tags_nested",
"query": {
"bool": {
"filter": [
{
"term": {
"host.tags_nested.tag_key": "example_key"
}
}
]
}
}
}
}
}
According to the ES docs, you can do a nested query to query within a nested doc, by passing a path which corresponds to the field name of the nested doc. But this seems not to work when the path is within an inner object and needs to be accessed using dot notation.
Any ideas?
Try this. Term Query searches for exact words which we specify. So, for that use fieldname.keyword because keyword stores exact text as we index them.
{
"query": {
"nested": {
"path": "host.tags_nested",
"query": {
"bool": {
"filter": [
{
"term": {
"host.tags_nested.tag_key.keyword": "example_key"
}
}
]
}
}
}
}
}

Querying Nested JSON based on 1 term value

I have indexed JSON like below format
JSON:
{"work":[{"organization":"abc", end:"present"},{"organization":"edf", end:"old"}]}
{"work":[{"organization":"edf", end:"present"},{"organization":"abc", end:"old"}]}
I want to query records where organization is "abc" and end is "present"
but below query is not working
work.0.organization: "abc" AND work.0.end:"present"
No records are matched
if I give query like below
work.organization: "abc" AND work.end:"present"
Both the records are matched. Whereas only the first record is what I want
The matched record should be only the below
{"work":[{"organization":"abc", end:"present"},{"organization":"edf", end:"old"}]}
You have to use nested_types. First map work as nested type in elastic using following mappings
PUT index_name_3
{
"mappings": {
"document_type" : {
"properties": {
"work" : {
"type": "nested",
"properties": {
"organization" : {
"type" : "text"
},
"end" : {
"type" : "text"
}
}
}
}
}
}
}
Use the following query to do nested filter match and innerhits
{
"query": {
"nested": {
"path": "work",
"inner_hits": {},
"query": {
"bool": {
"must": [{
"term": {
"work.organization": {
"value": "abc"
}
}
},
{
"term": {
"work.end": {
"value": "present"
}
}
}
]
}
}
}
}
}

Elasticsearch: Filter documents with empty geo_point value

I am trying to query an elasticsearch index for documents with an empty geo_point field. The field exists but it's blank (example below). A query which works for filtering string fields does not work for geo_point fields.
Document:
"_source": {
"latitudeLongitude": "",
"pickupLocationZipcode": "",
}
Query that works for filtering string fields but not geo_point fields:
{
"query": {
"filtered": {
"filter": {
"term": {
"latitudeLongitude": ""
}
}
}
}
}
Mapping:
"latitudeLongitude": {
"type": "geo_point"
}
"pickupLocationZipcode": {
"index": "not_analyzed",
"type": "string",
"copy_to": [
"pickup_location_zipcode"
]
}
You can use the missing query for this and it will find your document
{
"query": {
"filtered": {
"filter": {
"missing": {
"field": "latitudeLongitude",
"existence": false,
"null_value": true
}
}
}
}
}

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