TL;DR
Nest is creating an extra inner Bool.Match
when I try to match more than one thing in a should
clause (in bool context)
I am using Nest 5.6.1 and I'm trying to write the following query:
{
"query": {
"bool": {
"minimum_should_match": 2,
"should": [
{
"exists": {
"field": "B"
}
},
{
"exists": {
"field": "A"
}
},
{
"match": {
"fields.MachineName": "MY_Machine"
}
}
],
"filter": [
{
"range": {
"@timestamp": {
"gte": "2018-09-03T00:00:00",
"lt": "2018-09-04T00:00:00"
}
}
}
]
}
}
}
I tried to achieve it in the following way:
var searchResponse = connection.Search<ExcludedCusipsStructLog>(sd => sd
.Index(DefaultIndex)
.From(0)
.Size(1000)
.Type(LogType.ProxyLog)
.Query(q => q
.Bool(b => b
.Should(sh => sh
.Exists(e => e
.Field(fi => fi.A)
)
&& sh
.Exists(e => e
.Field(fi => fi.B)
)
&& sh
.Match(ma => ma
.Field(f => f.MachineName)
.Query("MY_Machine")
)
)
.MinimumShouldMatch(2)
.Filter(fi => fi
.DateRange(r => r
.Field(f => f.Timestamp)
.GreaterThanOrEquals(dateToSearch)
.LessThan(dateToSearch.AddDays(1))
)
)
)
)
);
The problem is that nest generating this request:
{
"from": 0,
"size": 1000,
"query": {
"bool": {
"should": [{
"bool": {
"must": [{
"exists": {
"field": "fields.invalidPositionList"
}
}, {
"exists": {
"field": "fields.excludedCusips"
}
}, {
"match": {
"fields.MachineName": {
"query": "GSMSIMPAPUA01"
}
}
}]
}
}],
"filter": [{
"range": {
"@timestamp": {
"gte": "2018-09-06T00:00:00",
"lt": "2018-09-07T00:00:00"
}
}
}],
"minimum_should_match": 2
}
}
}
I also figured out that if I look only one field in the Should clause - Nest is creating a good query - what get me to think that I should add the additional fields in a different way (which I didn't found)
As mentioned in the comment by @KozhevnikovDmitry.
I was supposed to use a coma instead of an &&
i.e. The correct way is:
var searchResponse = connection.Search<ExcludedCusipsStructLog>(sd => sd
.Index(DefaultIndex)
.From(0)
.Size(1000)
.Type(LogType.ProxyLog)
.Query(q => q
.Bool(b => b
.Should(sh => sh
.Exists(e => e
.Field(fi => fi.A)
)
,sh => sh
.Exists(e => e
.Field(fi => fi.B)
)
,sh => sh
.Match(ma => ma
.Field(f => f.MachineName)
.Query("MY_Machine")
)
)
.MinimumShouldMatch(2)
.Filter(fi => fi
.DateRange(r => r
.Field(f => f.Timestamp)
.GreaterThanOrEquals(dateToSearch)
.LessThan(dateToSearch.AddDays(1))
)
)
)
)
);