Nested bool query with multiple must and should - elasticsearch

Look at my use case below
Two nested fields
base1.point1
base1.point2
base1.point3
base1.point4
and
base2.point1
base2.point2
base2.point3
base2.point4
search condition
(
(base1.point1 AND base1.point2) OR (base1.point2 AND base1.point3)
)
AND
(
(base2.point1 AND base2.point2) OR (base2.point2 AND base2.point3)
)
Please help for writing above in a single query.

Note that I'm assuming that when you meant nested you are actually talking about Nested Datatype and not plain Object Datatype
Also looking at your question, you are only concerned if the nested fields exists or not, regardless of their values. For such use cases you would need to make use of Exists Query.
Below is how my Nested Query would be:
POST <you_index_name>/_search
{
"query":{
"bool":{
"must":[
{
"bool":{
"should":[
{
"bool":{
"must":[
{
"nested":{
"path":"base1",
"query":{
"exists":{
"field":"base1.point1"
}
}
}
},
{
"nested":{
"path":"base1",
"query":{
"exists":{
"field":"base1.point2"
}
}
}
}
]
}
},
{
"bool":{
"must":[
{
"nested":{
"path":"base1",
"query":{
"exists":{
"field":"base1.point2"
}
}
}
},
{
"nested":{
"path":"base1",
"query":{
"exists":{
"field":"base1.point3"
}
}
}
}
]
}
}
]
}
},
{
"bool":{
"should":[
{
"bool":{
"must":[
{
"nested":{
"path":"base2",
"query":{
"exists":{
"field":"base2.point1"
}
}
}
},
{
"nested":{
"path":"base1",
"query":{
"exists":{
"field":"base2.point2"
}
}
}
}
]
}
},
{
"bool":{
"must":[
{
"nested":{
"path":"base2",
"query":{
"exists":{
"field":"base2.point2"
}
}
}
},
{
"nested":{
"path":"base2",
"query":{
"exists":{
"field":"base2.point3"
}
}
}
}
]
}
}
]
}
}
]
}
}
}
Hope this helps!

Related

why minimum_should_match does not return multiple match?

i am refering to this question
How to use "OR" in Dev Tool Query
While trying to extend this to 3 Match with a minimum should match number to 2 it does not return any when i set it like this ""minimum_should_match":1" its works, but only gives 1 match, but when i do like this ""minimum_should_match":2" then it does not return anything, where as i know the query should found minimum 2 match which are in the log
so what i am doing wrong ?
GET _search
{
"query":{
"bool":{
"must":[
{
"match":{
"log.file.path":"mylog.log"
}
},
{
"term":{
"GPS-LOG.IMEI":{
"value":"1234567"
}
}
},
{
"bool":{
"should":[
{
"term":{
"GPS-LOG.COMMAND":{
"value":"HB"
}
}
},
term":{
"GPS-LOG.COMMAND":{
"value":"DB"
}
}
},
{
"term":{
"GPS-LOG.COMMAND":{
"value":"TR"
}
}
}
],
"minimum_should_match":1
}
}
],
"filter":{
"range":{
"#timestamp":{
"gte":"now-10m"
}
}
}
}
}
}

Elasticsearch Nested Query using Java API and Rest API Query Have Different Response

I am working on Elasticsearch(7.1.1) nested queries using java API for nested mapping index I have on my local machine. I am getting a response that are not the same as the rest api query I have.
I have a mapping that specify it is nested and it works fine when I tested it on kibana.
Here is an example query using Rest api.
GET my-index/_search
{
"query":{
"bool":{
"must":[
{
"nested":{
"path":"xx.yy.",
"query":{
"bool":{
"must":[
{
"match":{
"xx.yy.NAME":"cc"
}
},
{
"match":{
"xx.yy..VALUE":"ss"
}
}
]
}
}
}
},
{
"nested":{
"path":"xx.yy",
"query":{
"bool":{
"must":[
{
"match":{
"xx.yy.NAME":"ff"
}
},
{
"match":{
"xx.yy.VALUE":"ee"
}
}
]
}
}
}
},
{
"nested":{
"path":"xx.yy",
"query":{
"bool":{
"must":[
{
"match":{
"xx.yy.NAME":"kk"
}
},
{
"match":{
"xx.yy.VALUE":"gg"
}
}
]
}
}
}
}
]
}
}
}
And here is an equivalent java code I come up with.
searchSourceBuilder.query( QueryBuilders.boolQuery ()
.must(QueryBuilders.nestedQuery( path, matchQuery ( fNameOne, fValueOne ),ScoreMode.Avg )).minimumShouldMatch ( 1 )
.must(QueryBuilders.nestedQuery( path, matchQuery ( fNameTwo, fValueTwo ),ScoreMode.Avg )).minimumShouldMatch ( 1 )
.must(QueryBuilders.nestedQuery (path, matchQuery ( fNameThree, fValueThree ),ScoreMode.Avg )).minimumShouldMatch(1));
Can anyone point me where I made a mistake or give me direction how to tackle this problem? Your help is highly appreciated.

Filtering ElasticSearch query where date value is lte a given value or missing

I need to filter an ES query where the value of a date field is LTE a given value or the field is missing altogether. Here's my query at this point:
{
"from":0,
"size":50,
"query":{
"bool":{
"filter":[
{
"term":{
"corpusid.string.as_is":"42:6:4"
}
},
{
"nested":{
"path":"category.object",
"query":{
"bool":{
"must":[
{
"bool":{
"should":[
{
"range":{
"category.object.startdate":{
"lte":"2021-03-09T19:32:11.316Z"
}
}
},
{
"must_not":[
{
"exists":{
"field":"category.object.startdate"
}
}
]
}
]
}
}
]
}
}
}
}
]
}
}
}
When I submit that query, I get the error "[must_not] query malformed, no start_object after query name". We're running ElasticSearch version 5.3.1 in case that matters.
I refactored the query a bit. Removed a must, added a bool for the must_not.
{
"from":0,
"size":50,
"query":{
"bool":{
"filter":[
{
"term":{
"corpusid.string.as_is":"42:6:4"
}
},
{
"nested":{
"path":"category.object",
"query":{
"bool":{
"should": [
{
"range":{
"category.object.startdate":{
"lte":"2021-03-09T19:32:11.316Z"
}
}
},
{
"bool": {
"must_not": {
"exists": {
"field": "category.object.startdate"
}
}
}
}
]
}
}
}
}
]
}
}
}

How to filter a field using Elastic Search

I'm trying to create a query with elasticsearch to filter the records of the same city and price.
But the city filter is not working.
POST diadeturista/services/_search
{
"query":{
"bool":{
"must":[
],
"filter":{
"bool":{
"must":{
"terms":{
"city":[
"Contagem"
]
},
"range":{
"price_adult":{
"lte":"300",
"gte":"150"
}
}
}
}
}
}
}
}
SHow me this error:
[terms] malformed query, expected [END_OBJECT] but found [FIELD_NAME]
I think what you want todo is
{
"query":{
"bool":{
"must": [
{
"terms":{
"city":[
"Contagem"
]
}
},
{
"range":{
"price_adult":{
"lte":"300",
"gte":"150"
}
}
}
]
}
}
}

Which DSL is correct for performing a pre-filtered query?

I've looked back at some queries I have saved, and it appears I've managed to achieve essentially the same query in three different ways. They all return the same data, but which one is 'correct'? I.e., which one contains no superfluous code and is most performant?
Option 1
{
"query":{
"bool":{
"must":[
{
"match":{
"event":"eventname"
}
},
{
"range":{
"#timestamp":{
"gt":"now-70s"
}
}
}
]
}
},
"aggs":{
"myterms":{
"terms":{
"field":"fieldname"
}
}
}
}
Option 2
{
"query":{
"filtered":{
"filter":{
"bool":{
"must":[
{
"match":{
"event":"eventname"
}
},
{
"range":{
"#timestamp":{
"gt":"now-70s"
}
}
}
]
}
}
}
},
"aggs":{
"myterms":{
"terms":{
"field":"fieldname"
}
}
}
}
Option 3
{
"query":{
"filtered":{
"query":{
"bool":{
"must":[
{
"match":{
"event":"eventname"
}
},
{
"range":{
"#timestamp":{
"gt":"now-70s"
}
}
}
]
}
}
}
},
"aggs":{
"myterms":{
"terms":{
"field":"fieldname"
}
}
}
}
If I were to guess, I'd go for Option 2, as the others appear that they might be running match as query. But the documentation is pretty confusing regarding the correct form that DSL queries should take.
Based on your comment, I'd go for option 2 but with a simple term filter for starters instead of match which isn't allowed in filters.
{
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"term": {
"event": "eventname"
}
},
{
"range": {
"#timestamp": {
"gt": "now-70s"
}
}
}
]
}
}
}
},
"aggs": {
"myterms": {
"terms": {
"field": "event"
}
}
}
}

Resources