Querying nested objects not working - elasticsearch

This is a really basic question but I just cannot find what's wrong in my query.
The mapping:
{
"typeName": {
"properties": {
"active": {
"type": "boolean"
},
"id": {
"type": "string",
"index": "not_analyzed"
},
"values": {
"type": "nested",
"properties": {
"by": {
"type": "string",
"analyzer": "english"
},
"idChatRoom": {
"type": "string",
"analyzer": "english"
},
"message": {
"type": "string",
"analyzer": "english"
}
}
}
}
As you can see there is a nested object called "values". If I try to run the following query:
GET plugg_co/chatmessage_50813808/_search
{
query: {
nested: {
path: "values",
query: {
filtered: {
filter: {
term: { "values.idChatRoom": "id-123" }
}
}
}
}
}
}
I don't get any result back (the index is not empty! I checked!). Any idea?
Thanks

There is no problem in nested query. Nested query is fine.But since idChatRoom is analyzed that's why you should not use term query on it.Instead you should use match query. Change you query to:
GET plugg_co/chatmessage_50813808/_search
{
"query": {
"nested": {
"path": "values",
"query": {
"match": {
"values.idChatRoom": "id-123"
}
}
}
}
}
If you want to use term query you can make it not analysed or multifield. You can refer to https://www.elastic.co/guide/en/elasticsearch/reference/2.x/_multi_fields.html for more information on multifield
Hope it helps.

Related

How can I get parent with all children in one query

I have following mapping:
PUT /test_products
{
"mappings": {
"_doc": {
"properties": {
"type": {
"type": "keyword"
},
"name": {
"type": "text"
},
"entity_id": {
"type": "integer"
},
"weighted": {
"type": "integer"
}
"product_relation": {
"type": "join",
"relations": {
"window": "simple"
}
}
}
}
}
}
I want to get "window" products with all "simple"s but only where one or more "simple"s have property "weighted" = 1
I wrote following query:
GET test_products/_search
{
"query": {
"has_child": {
"type": "simple",
"query": {
"term": {
"weighted": 1
}
},
"inner_hits": {}
}
}
}
But I've got "window"s with "simple"s which are match to the term. In other words I want to filter "window"s list by "simple"'s option and get all matched "window"s with all their "simple"s. Is it possible without "nested" in one query? Or I have to do some queries?
OK. Luckily, I need to get only one "window" product with all it's children by it's ID, so I found parent_id query which can helps me with this task.
Now I have following query:
GET test_products/_search
{
"query": {
"parent_id": {
"type": "simple",
"id": "window-1"
}
}
}
Unfortunately, I have to execute 2 queries (has_child and then parent_id) instead of one but it's OK for me.

ElasticSearch: Getting parent's fields from a search on the child type

I have an index with two type (Parent/CHild relation) like this :
{
"myindex": {
"mappings": {
"b": {
"_parent": {
"type": "a"
},
"properties": {
"b_propertie1": {
"type": "string",
"analyzer": "keyword_analyzer"
},
"b_propertie2": {
"type": "string",
"analyzer": "keyword_analyzer"
}
}
},
"a": {
"properties": {
"a_propertie1": {
"type": "string",
"analyzer": "keyword_analyzer"
},
"a_propertie2": {
"type": "string",
"analyzer": "keyword_analyzer"
}
}
}
}
}
}
And i want to make a query that returns the fields of the parent and the child
POST /myindex/b/_search
{
"fields" : ["b_propertie1", "b_propertie2", "a_propertie1", "a_propertie2"],
"query": {
"match": {
"b_propertie1": "SOMETHING"
}
}
}
Is there any way to do it ? and how?
Thank you.
ElasticSearch cannot merge fields from parent and child documents.
What you can do is to use the has_child query, which returns you parent documents that have child documents that match your query. By specifying the inner_hits parameters you also get as inner objects the child documents that matched the query.
"query": {
"has_child": {
"type": b,
"query": {
"match": {
"b_propertie1": "SOMETHING"
}
},
"inner_hits": {
'_source': {
'includes': ['b_propertie1', 'b_propertie2']
}
}
}
}
Then in your app, you can merge the fields from parent and child documents to get the result you want.
I hope it helps. :)

Search for documents in elasticsearch and then query the nested fields

I have an index like this:
{
"rentals": {
"aliases": {},
"mappings": {
"rental": {
"properties": {
"address": {
"type": "text"
},
"availability": {
"type": "nested",
"properties": {
"chargeBasis": {
"type": "text"
},
"date": {
"type": "date"
},
"isAvailable": {
"type": "boolean"
},
"rate": {
"type": "double"
}
}
}
}
And this is my use case:
I need to search for all the "rentals" that have a given address.
This is easy and done
I need to get "availability" data for all those "rentals" searched; only for today's date.
This is the part where I'm stuck at, how do I query the nested documents of all the "rentals"?
You need to use the nested query:
Because nested objects are indexed as separate hidden documents, we can’t query them directly. Instead, we have to use the nested query to access them.
Try something like:
{
"query": {
"nested": {
"path": "availability",
"query": {
"term": {
"availability.date": "2015-01-01"
}
}
}
}
}

Update and search in multi field properties in ElasticSearch

I'm trying to use multi field properties for multi language support. I created following mapping for this:
{
"mappings": {
"product": {
"properties": {
"prod-id": {
"type": "string"
},
"prod-name": {
"type": "string",
"fields": {
"en": {
"type": "string",
"analyzer": "english"
},
"fr": {
"type": "string",
"analyzer": "french"
}
}
}
}
}
}
}
I created test record:
{
"prod-id": "1234567",
"prod-name": [
"Test product",
"Produit d'essai"
]
}
and tried to query using some language:
{
"query": {
"bool": {
"must": [
{"match": {
"prod-name.en": "Produit"
}}
]
}
}
}
As a result I got my document. But I expected that I will have empty result when I use French but choose English. It seems ElasticSearch ignores which field I specified in query. There is no difference in search result when I use "prod-name.en" or "prod-name.fr" or just "prod-name". Is this behaviour expected? Should I do some special things to have searching just in one language?
Another problem with updating multi field property. I can't update just one field.
{
"doc" : {
"prod-name.en": "Test"
}
}
I got following error:
{
"error": {
"root_cause": [
{
"type": "mapper_parsing_exception",
"reason": "Field name [prod-name.en] cannot contain '.'"
}
],
"type": "mapper_parsing_exception",
"reason": "Field name [prod-name.en] cannot contain '.'"
},
"status": 400
}
Is there any way to update just one field in multi field property?
In your mapping, the prod-name.en field will simply be analyzed using the english analyzer and the same for the french field. However, ES will not choose for you which value to put in which field.
Instead, you need to modify your mapping like this
{
"mappings": {
"product": {
"properties": {
"prod-id": {
"type": "string"
},
"prod-name": {
"type": "object",
"properties": {
"en": {
"type": "string",
"analyzer": "english"
},
"fr": {
"type": "string",
"analyzer": "french"
}
}
}
}
}
}
}
and input document to be like this and you'll get the results you expect.
{
"prod-id": "1234567",
"prod-name": {
"en": "Test product",
"fr": "Produit d'essai"
}
}
As for the updating part, your partial document should be like this instead.
{
"doc" : {
"prod-name": {
"en": "Test"
}
}
}

Elasticsearch Aggregation - Unable to perform aggregation to object

I have a mapping with an inner object as follows:
{
"mappings": {
"_all": {
"enabled": false
},
"properties": {
"foo": {
"name": {
"type": "string",
"index": "not_analyzed"
},
"address": {
"type": "object",
"properties": {
"address": {
"type": "string"
},
"city": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
}
}
When I try the following aggregation it does not return any data:
post data:*/foo/_search?search_type=count
{
"query": {
"match_all": {}
},
"aggs": {
"unique": {
"cardinality": {
"field": "address.city"
}
}
}
}
When I try to put field city or address.city, aggregation returns zero but if i put foo.address.city it is then when i get the correct respond by elasticsearch. This also affects kibana behavior
Any ideas why this is happening? I saw there is a mapping refactoring that might affects this. I use elasticsearch version 1.7.1
To add on this if, I use the relative path in a search query as follows it works normally:
"query": {
"filtered": {
"filter": {
"term": {
"address.city": "london"
}
}
}
}
Seems its this same issue.
This is seen when the type name and field name is same.

Resources