I need to search in array of ElasticSearch
. I've documents like
{
"product_name": "iPhone 9",
"features":[
{
"color": "black",
"memory": "128GB"
},
{
"color": "white",
"memory": "64GB"
}
],
},
{
"product_name": "iPhone 9",
"features":[
{
"color": "black",
"memory": "64GB"
},
{
"color": "white",
"memory": "64GB"
}
],
}
I want to search iphone 9
with color = black
and memory = 64GB
. I'm using following query
_search?q=product_name:"iPhone 9" AND features.color:"black" AND features.memory:"64GB"
Only the second record from the document should get listed, but this query is displaying both the records as it matches color
with first array and memory
with second array. How can I achieve the correct result?
CodePudding user response:
Elasticsearch has no concept of inner objects. Therefore, it flattens object hierarchies into a simple list of field names and values.
Your document will be transformed internally and stored as
{
"product_name" : "iPhone 9",
"features.color" : [ "black", "white" ],
"features.memory" : [ "128GB", "64GB" ]
}
The associate between color and memory is lost.
If you need to maintain independence of each inner object of array , you need to use nested type
Nested type can be only queried using nested query.
PUT index-name
{
"mappings": {
"properties": {
"features": {
"type": "nested"
}
}
}
}
PUT index-name/_doc/1
{
"product_name": "iPhone 9",
"features":[
{
"color": "black",
"memory": "128GB"
},
{
"color": "white",
"memory": "64GB"
}
],
}
GET index-name/_search
{
"query": {
"nested": {
"path": "features",
"query": {
"bool": {
"must": [
{ "match": { "features.color": "black" }},
{ "match": { "features.memory": "64GB" }}
]
}
}
}
}
}