Вы должны иметь возможность объединить запрос exists
с запросом range
в AvailableTo
, чтобы включить документы, для которых существует поле AvailableTo
и которые должны удовлетворять условию диапазона, и создать дизъюнкцию с AvailableTo
существует запрос в предложении bool
query must_not
, т.е. инвертирует существующий.
Что-то вроде следующего (я закомментировал запросы, которые не были предоставлены)
var client = new ElasticClient(settings);
var request = new
{
AddDateFilter = true
};
var boolQuery = new BoolQueryDescriptor<AttractionDocument>();
boolQuery.Must(
// mn => AddRegionQuery(permissions, mn),
// mn => AddOffersQuery(permissions, mn),
mn => request.AddDateFilter ? mn.DateRange(d => d.Field(f => f.AvailableFrom).LessThanOrEquals(DateTime.Now)) : mn,
mn => request.AddDateFilter ? (mn.Exists(d => d.Field(f => f.AvailableTo)) &&
mn.DateRange(d => d.Field(f => f.AvailableTo).GreaterThanOrEquals(DateTime.Now))) ||
!mn.Exists(d => d.Field(f => f.AvailableTo)) : mn //,
// mn => AddGenresQuery(genres, mn)
);
client.Search<AttractionDocument>(s => s
.Query(q => q.Bool(b => boolQuery))
);
Это производит следующий запрос
{
"query": {
"bool": {
"must": [
{
"range": {
"availableFrom": {
"lte": "2018-11-15T20:18:10.528482+10:00"
}
}
},
{
"bool": {
"should": [
{
"bool": {
"must": [
{
"exists": {
"field": "availableTo"
}
},
{
"range": {
"availableTo": {
"gte": "2018-11-15T20:18:10.5304815+10:00"
}
}
}
]
}
},
{
"bool": {
"must_not": [
{
"exists": {
"field": "availableTo"
}
}
]
}
}
]
}
}
]
}
}
}
Поскольку диапазон исуществующие запросы являются предикатами (документ либо соответствует условию, либо нет) в отличие от запросов, которые должны вычислять оценки релевантности, это могут быть bool
query filter
условия
boolQuery.Must(
// Uncomment below queries, or add (QueryContainer[])null to run
// mn => AddRegionQuery(permissions, mn),
// mn => AddOffersQuery(permissions, mn),
// mn => AddGenresQuery(genres, mn)
).Filter(
mn => request.AddDateFilter ? mn.DateRange(d => d.Field(f => f.AvailableFrom).LessThanOrEquals(DateTime.Now)) : mn,
mn => request.AddDateFilter ? (+mn.Exists(d => d.Field(f => f.AvailableTo)) &&
+mn.DateRange(d => d.Field(f => f.AvailableTo).GreaterThanOrEquals(DateTime.Now))) ||
!mn.Exists(d => d.Field(f => f.AvailableTo)) : mn
);
client.Search<AttractionDocument>(s => s
.Query(q => q.Bool(b => boolQuery))
);
, которые создаютquery
{
"query": {
"bool": {
"filter": [
{
"range": {
"availableFrom": {
"lte": "2018-11-15T20:22:25.4556963+10:00"
}
}
},
{
"bool": {
"should": [
{
"bool": {
"filter": [
{
"exists": {
"field": "availableTo"
}
},
{
"range": {
"availableTo": {
"gte": "2018-11-15T20:22:25.4587138+10:00"
}
}
}
]
}
},
{
"bool": {
"must_not": [
{
"exists": {
"field": "availableTo"
}
}
]
}
}
]
}
}
]
}
}
}
Перегрузка операторов на запросы действительно помогает здесь, более кратко писать сложные запросы bool