I have a question that is related to this one (execute a filter on nested document only if it exists), but with a twist.
The older question is about filtering on a nested document, but this approach fails if a nested field is present in the mapping of one index, but not the other.
To make it clearer, here is an example:
PUT temp1?include_type_name=false
{
"mappings": {
"properties": {
"nst": {
"type": "nested",
"properties": {
"a": {
"type": "keyword"
},
"b": {
"type": "keyword"
}
}
},
"foo": {
"type": "text"
},
"bar": {
"type": "text"
}
}
}
}
PUT temp2?include_type_name=false
{
"mappings": {
"properties": {
"foo": {
"type": "text"
}
}
}
}
PUT temp1/_doc/1
{
"nst": {
"a": 1,
"b": 2
},
"foo": "my text",
"bar": "more text"
}
PUT temp2/_doc/1
{
"foo": "some other text"
}
Now if I want to extract all documents from both indices, that don't have a field bar
, that's easy:
GET temp*/_search
{
"query": {
"bool": {
"must_not": [
{
"exists": {
"field": "bar"
}
}
]
}
}
}
But what if I want to get all documents that don't have a field nst
?
Simply replacing bar with nst
or nst.a
doesn't work, as nst
is not a field of itself , and nst.a
is a nested field, so it's not accessible. This means exists
returns false
for both, and I get 2 documents.
But I get an error if I follow the approach for a nested field:
GET temp*/_search
{
"query": {
"bool": {
"must_not": [
{
"nested": {
"path": "nst",
"query": {
"exists": {
"field": "nst.a"
}
}
}
}
]
}
}
}
For the index temp2
, the query failed to find nested object under path [nst]
.
Understandable, but is there a way to still query for this?
The only way I can think of is including a nested field nst
in each of my indices, with the sole purpose of leaving it empty. That seems ugly, and in my real data I have more then 2 indices.
Any ideas?