Complex Nested Query Where to Place Bool Match - elasticsearch

I have a complex index within Elastic that I need to query by 3 parameters.
Thanks to this answered question I am able to query by 2 of the 3 parameters, however the 3rd parameter is not at the same nested level as the other two.
The schema looks this..
The following query works for the 2 of the 3 parameters...
But the 3rd parameter is at a different level the the other two so this query does not return the expected document.
Given that the bool match query for "boundedContexts.aggregateRoot.aggregateType.name" is at a different nested level, how would I write this query so that it will query on that field ?

This works...
{
"query": {
"nested": {
"path": "boundedContexts",
"query": {
"nested": {
"path": "boundedContexts.aggregateRoots",
"query": {
"bool": {
"must": [
{ "match": { "boundedContexts.aggregateRoots.aggregateType.name": "Aggregate" } },
{ "nested": {
"path": "boundedContexts.aggregateRoots.modelMetaData",
"query": {
"bool": {
"must": [
{ "match": { "boundedContexts.aggregateRoots.modelMetaData.modelReferenceId": "4e7c5c0e-93a7-4bf6-9705-cf1327760e21" } },
{ "match": { "boundedContexts.aggregateRoots.modelMetaData.modelType.name": "AggregateRoot" } }
]
}
}
}
}
]
}
}
}
}
}
},
"size": 1,
"sort": [
{
"generatedDate": {
"order": "desc"
}
}
]
}

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"
}
}
]
}
}
}
}
]
}
}
}

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.

Get unique data from a field using ElasticSearch query DSL in Kibana

I have already various queries that collect data and show it in the Kibana dashboard.
Now I would like to get unique values from my result data. How can I write the query DSL for that.
Basically I would like to get unique value for the field contextMap.connectionid. Is there a way do achieve that using something similar to this example?
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "app",
"query": {
"bool": {
"must": [
{
"match": {
"app.key": "contextMap.connectionid"
}
}
]
}
}
}
}
]
}
}
}
You can calculate distinct count with the help of aggregation .
So, your search query is :
Search Query :
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "app",
"query": {
"bool": {
"must": [
{
"match": {
"app.key": "contextMap.connectionid"
}
}
]
}
}
}
}
]
}
},
"aggs": {
"uniqueconnectionId": {
"terms": {
"field": "contextMap.connectionid.keyword"
}
}
}
}
You can refer here for calculating distinct values of a field https://discuss.elastic.co/t/get-distinct-values-from-a-field-in-elasticsearch/99783

Elasticsearch 5 combine bool terms and nested term filters

There is documentation for for nested query terms filter https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-nested-query.html and bool term filter https://www.elastic.co/guide/en/elasticsearch/reference/5.5/query-dsl-bool-query.html
Nested is array of objects. Not just object. That is point i can't use simple bool term filter.
my query looks like:
{
"query": {
"bool": {
"filter": [
{
"term": {
"access_account.nid": 17,
"destroyed_at": null
}
}
],
"must": {
"match_all": {}
}
},
"nested": {
"path": "categories",
"query": {
"bool": {
"filter": [
{
"terms": {
"categories.id": [
15, 17
]
}
}
]
}
}
}
}
}
Filters are array because i have in real more terms filters.
I got this response
reason": "[bool] malformed query, expected [END_OBJECT] but found [FIELD_NAME]"
Is there any solution how to combine parent/nested term filters? Official documentation doesn't help.
My Elastic version is 5.4
Thanks.
You're almost there, your nested query just needs to go inside the bool/filter clause:
{
"query": {
"bool": {
"filter": [
{
"term": {
"access_account.nid": 17,
"destroyed_at": null
}
},
{
"nested": {
"path": "categories",
"query": {
"bool": {
"filter": [
{
"terms": {
"categories.id": [
15,
17
]
}
}
]
}
}
}
}
]
}
}
}

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