Reputation: 5556
I'm trying to create a query/filter that matches a document only if a number of conditions are met on the same item of an array.
Let's say this is the document:
{
arr: [
{ "f1" : "a" , f2 : true },
{ "f1" : "b" , f2 : false}
]
}
I want to be able to retrieve documents that have N conditions matching on the same element. For example: arr.f1 == "a" AND arr.f2 == true
should match the document but arr.f1 == "b" AND arr.f2 == true
should not.
I'm trying nested bool filters (I have other filters apart from this one) but it doesn't work, something in the lines of
"bool" : {
"must": [
{ some other filter },
{"bool": {"must" : [
{"term" : {"arr.f1" : "a"}},
{"term" : {"arr.f2" : true}},
] }}
]
}
Any idea how to do that? thanks
edit: I changed the mapping and now a nested query works as per Val's response. I'm now not able to do an "exists" filter on the nested field:
A simple { "filter" : {"exists" : { "field" : "arr" } } }
search returns no hits. How do I do that?
edit: It looks like I need to do a nested exists filter to check that a field inside the nested object exists. something like:
"filter" : {
"nested" : {"path" : "arr", "filter" : {"exists" : { "field" : "f1" } }}
}
edit: argh - now highlight doesn't work anymore:
"highlight" : {
"fields" : [
{"arr.f1" : {}},
]
}
Worked around that by adding include_in_parent : true
and querying both the nested field and the root object. It's just awful. If anyone has a better idea, they're more than welcome!
{
"query" : {
"bool" : {
"must": [
{"term" : { "arr.f1" : "a" }},
{ "nested" : { "path" : "arr",
"query" : { "bool" : { "must" : [
{"term" : { "arr.f1" : "a" }},
{"term" : { "arr.f2" : true }}
] } }
}}
]
}
},
"highlight" : {
"fields" : [
{"arr.f1" : {}},
]
}
}
In case you're wondering: it's legacy stuff. I can't reindex right now (that would be the obvious solution) and I need a quick & dirty workaround
Upvotes: 6
Views: 4056
Reputation: 217314
You need to set the type of your arr
field as nested
like this:
{
"your_type": {
"properties": {
"arr": {
"type": "nested",
"properties": {
"f1": {"type":"string"},
"f2": {"type":"boolean"}
}
}
}
}
}
Then you need to use a nested
query:
{
"nested" : {
"path" : "arr",
"query" : {
"bool" : {
"must" : [
{
"term" : {"arr.f1" : "a"}
},
{
"term" : {"arr.f2" : true}
}
]
}
}
}
}
Your exists
filter needs to specify the full field path
"filter" : {
"nested" : {"path" : "arr", "filter" : {"exists" : { "field" : "arr.f1" } }}
}
Upvotes: 6