Search in multiple index , 'query_shard_exception' when fields are not present - elasticsearch

I'm trying to search in multiple indexes, but the fields and mapping for each index are different. Like one index is having nested path.
When I'm trying to query on index's I'm getting error for the index which are not having the nested path.
{
"query": {
"bool": {
"should": [
{
"term": {
"a": "good"
}
},
{
"term": {
"a.b": "sample"
}
},
{
"nested": {
"path": "x.y.z",
"query": {
"bool": {
"should": [
{
"term": {
"x.y.z.id.keyword": "test#gamil.com"
}
}
]
}
}
}
}
]
}
}
}
in above the nested path x.y.z is only present for one index.
I tried finding a solution, found ignore_unavailable. But it will ignore the index not having nested path, but I need the document's in that index which matches other condition in the query.

Try the following query by replacing your-index with the name of the index that contains the nested field.
{
"query": {
"bool": {
"should": [
{
"term": {
"a": "good"
}
},
{
"term": {
"a.b": "sample"
}
},
{
"bool": {
"must": [
{
"term": {
"_index": "your-index"
}
},
{
"nested": {
"path": "x.y.z",
"query": {
"bool": {
"should": [
{
"term": {
"x.y.z.id.keyword": "test#gamil.com"
}
}
]
}
}
}
}
]
}
}
]
}
}
}

Related

Elasticsearch combine term and range query on nested key/value data

I have ES documents structured in a flat data structure using the nested data type, as they accept arbitrary JSON that we don't control, and we need to avoid a mapping explosion. Here's an example document:
{
"doc_flat":[
{
"key":"timestamp",
"type":"date",
"key_type":"timestamp.date",
"value_date":[
"2023-01-20T12:00:00Z"
]
},
{
"key":"status",
"type":"string",
"key_type":"status.string",
"value_string":[
"warning"
]
},
... more arbitrary fields ...
],
}
I've figured out how to query this nested data set to find matches on this arbitrary nested data, using a query such as:
{
"query": {
"nested": {
"path": "doc_flat",
"query": {
"bool": {
"must": [
{"term": {"doc_flat.key": "status"}},
{"term": {"doc_flat.value_string": "warning"}}
]
}
}
}
}
}
And I figured out how to find documents matching a particular date range:
{
"query": {
"nested": {
"path": "doc_flat",
"query": {
"bool": {
"must": [
{"term": {"doc_flat.key": "timestamp"}},
{
"range": {
"doc_flat.value_date": {
"gte": "2023-01-20T00:00:00Z",
"lte": "2023-01-21T00:00:00Z"
}
}
}
]
}
}
}
}
}
But I'm struggling to combine these two queries together, in order to search for documents that have a nested documents which match these two conditions:
a doc_flat.key of status, and a doc_flat.value_string of warning
a doc_flat.key of timestamp, and a doc_flat.value_date in a range
Obviously I can't just shove the second set of query filters into the same must array, because then no documents will match. I think I need to go "one level higher" in my query and wrap it in another bool query? But I can't get my head around how that would look.
You tried two nested inside Bool query?
{
"query": {
"bool": {
"filter": [
{
"nested": {
"path": "doc_flat",
"query": {
"bool": {
"must": [
{
"term": {
"doc_flat.key": "timestamp"
}
},
{
"range": {
"doc_flat.value_date": {
"gte": "2023-01-20T00:00:00Z",
"lte": "2023-01-21T00:00:00Z"
}
}
}
]
}
}
}
}
],
"must": [
{
"nested": {
"path": "doc_flat",
"query": {
"bool": {
"must": [
{
"term": {
"doc_flat.key": "status"
}
},
{
"term": {
"doc_flat.value_string": "warning"
}
}
]
}
}
}
}
]
}
}
}

Sql query on elastic 6.8 does not work as expected. Array of nested objects are flattened same as of type object

Thanks for the answer in advance.
I am running a query
SELECT key
FROM records_index
WHERE
(product_nested_field.code = '1234' and product_nested_field.codeset = 'category1' OR product_nested_field.code = '444' and product_nested_field.codeset = 'category1')
AND (role_name IN ('user', 'admin'))
GROUP BY records_uuid
In records_index I have record with two products
[
{codeset: category1, code:444},
{codeset: category2, code:1234}
]
The problem is that query does find a specified record.
such behavior is expected for "type": "object" but why I am getting that result for product_nested_field of type nested?
when I translate SQL to JSON I am getting
{
"bool": {
"must": [
{
"bool": {
"must": [
{
"nested": {
"query": {
"term": {
"product_nested_field.codeset": {
"value": "category1"
}
}
}
}
}
]
}
},
{
"bool": {
"must": [
{
"bool": {
"should": [
{
"nested": {
"query": {
"term": {
"product_nested_field.code": {
"value": "1234"
}
}
}
}
},
{
"nested": {
"query": {
"term": {
"product_nested_field.code": {
"value": "444"
}
}
}
}
}
]
}
}
]
}
}
],
"adjust_pure_negative": true,
"boost": 1.0
}
}
why elastic moves product_nested_field.codeset = 'category1' into separate nested query.

Elasticsearch filter by matching query in all nested documents

I have a problem with filtering elastic documents by nested documents.
In general document has a list of nested assets and each asset have a list of teamIds
Sample cut off document:
{
"assets":[
{
"id":100,
"teams":[
1
]
},
{
"id":101,
"teams":[
4,
3
]
}
]
}
Expected result is to get root document where all assets have at least one matching team
I've tried:
{
"from": 0,
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"bool": {
"must": [
{
"nested": {
"path": "assets",
"query": {
"terms": {
"assets.teams": [
1
]
}
}
}
}
]
}
},
{
"bool": {
"must_not": [
{
"nested": {
"path": "assets",
"query": {
"bool": {
"must": [
{
"exists": {
"field": "assets"
}
}
]
}
}
}
}
]
}
}
]
}
}
]
}
},
"size": 999
}
Unfortunately this query return document. In this case I do expect it returns document if query contains ids like [1,3], [1,4] or [1,3,4]
Thanks in advance
To find a document where all nested documents contain any of given terms
{
"query": {
"bool": {
"must_not": [
{
"nested": {
"path": "assets",
"query": {
"bool": {
"must_not": [
{
"terms": {
"assets.teams": [
"1"
]
}
}
]
}
}
}
}
]
}
}
}
````
In the above, nested query returns documents where a nested document does not contain any of given term, then outer must_not excludes those documents.
In other words first find documents where a nested document doesnot contain given term and then exclude those documents.
If you want to include documents where teams field is not present use below
````
{
"query": {
"bool": {
"must_not": [
{
"nested": {
"path": "assets",
"query": {
"bool": {
"must": [
{
"exists": {
"field": "assets.teams"
}
}
],
"must_not": [
{
"terms": {
"assets.teams": [
"1"
]
}
}
]
}
}
}
}
]
}
}
}
````

How to combine must and must_not in elasticsearch with same field

i have elasticsearch 6.8.8, just for an example of my question. I want to create a query that gets me document with "Test" field with value "1", and i don't want to get "Test" field with value of "3", i know that i could write just the first expression without 3 and it will give me one document with value of "1". But i want to know, is there any way, that i can use must and must_not in the same time, on the same field and getting just the value of "1"?
I wrote this basic example to know what i mean:
{
"from": 0,
"query": {
"nested": {
"path": "attributes",
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"match": {
"attributes.key": {
"query": "Test"
}
}
},
{
"match": {
"attributes.value": {
"query": "1"
}
}
}
],
"must_not": [
{
"match": {
"attributes.key": {
"query": "Test"
}
}
},
{
"match": {
"attributes.value": {
"query": "3"
}
}
}
]
}
}
]
}
}
}
}
}
I use attributes as nested field with key-value field that use mapping as string type.
You'll need to leave out attributes.key:Test in the must_not because it filters out all Tests:
GET combine_flat/_search
{
"from": 0,
"query": {
"nested": {
"inner_hits": {},
"path": "attributes",
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"match": {
"attributes.key": {
"query": "Test"
}
}
},
{
"match": {
"attributes.value": {
"query": "1"
}
}
}
],
"must_not": [
{
"match": {
"attributes.value": {
"query": "3"
}
}
}
]
}
}
]
}
}
}
}
}
Tip: use inner_hits to just return the matched nested key-value pairs as opposed to the whole field.

Multiple values in nested elastic search 2 query

I have a nested object named 'bundles', that usually contains more than one object. Using this query I can succesfully query on the id of an object in bundles, but I fail to write a query that can query on multiple id's. Suggestions?
{
"query": {
"nested": {
"path": "bundles",
"query": {
"bool": {
"must": [
{
"match": {
"bundles.id": 43273
}
}
]
}
},
"inner_hits": {}
}
}
}
Perhaps you want "should" instead of "must" in the boolean filter. For example:
{
"query": {
"nested": {
"path": "bundles",
"query": {
"bool": {
"should": [
{
"match": {
"bundles.id": 43273
},
{
"match": {
"bundles.id": 433373
}
}
]
}
}
}
}
}
You could also use terms query if the field can be matched exactly. For example:
{
"query": {
"nested": {
"path": "bundles",
"query": {
"bool": {
"must": [
{
"terms": {
"bundles.id": [1140000000, 114]
}
}
]
}
}
}
}
}'

Resources