我使用ElasticSearch5.2和Nest客户端进行查询。我有一个日期范围的工作查询,如下所示:
var boolQuery = new BoolQueryDescriptor<AttractionDocument>();
//https://github.com/elastic/elasticsearch-net/issues/2570 must is not additive, we cannot split out query as before it all has to be one big one
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.DateRange(d => d.Field(f => f.AvailableTo).GreaterThanOrEquals(DateTime.Now)) : mn,
mn => AddGenresQuery(genres, mn)
);我遇到的问题是,AvailableTo并不总是被填充,因此对于某些文档,它将不存在。
我试图添加以下内容:
if (request.AddDateFilter)
{
boolQuery.MustNot(mn => mn.Exists(f => f.Field(e => e.AvailableTo)));
}现在的问题是查询变得过于限制性。理想的情况下,存在的部分,我想作为一个应该?我试图实现的是,如果我们有其他字段,忽略并返回没有日期的结果,则只为AvailableTo应用日期范围。如果我去掉AvailableTo部分,我就会得到结果。
发布于 2018-11-15 10:23:39
您应该能够将exists查询与AvailableTo上的range查询组合起来,以包含存在AvailableTo字段且必须满足范围条件的文档,并在bool Querymust_not子句中创建与AvailableTo AvailableTo查询的分离,即反转存在的文档。
如下所示(我已经注释掉了未提供的查询)
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查询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": {
"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查询。
发布于 2018-11-14 16:42:27
好吧,我想我已经研究过了。我取出了“必须日期”范围,并将其设为“应该”,所以现在的查询如下:
var boolQuery = new BoolQueryDescriptor<AttractionDocument>();
if (request.AddDateFilter)
{
boolQuery.Should(mn => mn.DateRange(d => d.Field(f => f.AvailableTo).GreaterThanOrEquals(DateTime.Now)));
}
//https://github.com/elastic/elasticsearch-net/issues/2570 must is not additive, we cannot split out query as before it all has to be one big one
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 => AddGenresQuery(genres, mn)
);现在,我在没有availableTo日期集的日期和匹配的范围内返回结果。
https://stackoverflow.com/questions/53304062
复制相似问题