首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >弹性嵌套查询字段应该存在过滤器

弹性嵌套查询字段应该存在过滤器
EN

Stack Overflow用户
提问于 2018-11-14 15:51:48
回答 2查看 2.8K关注 0票数 0

我使用ElasticSearch5.2和Nest客户端进行查询。我有一个日期范围的工作查询,如下所示:

代码语言:javascript
复制
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并不总是被填充,因此对于某些文档,它将不存在。

我试图添加以下内容:

代码语言:javascript
复制
if (request.AddDateFilter)
{
    boolQuery.MustNot(mn => mn.Exists(f => f.Field(e => e.AvailableTo)));
}

现在的问题是查询变得过于限制性。理想的情况下,存在的部分,我想作为一个应该?我试图实现的是,如果我们有其他字段,忽略并返回没有日期的结果,则只为AvailableTo应用日期范围。如果我去掉AvailableTo部分,我就会得到结果。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-11-15 10:23:39

您应该能够将exists查询与AvailableTo上的range查询组合起来,以包含存在AvailableTo字段且必须满足范围条件的文档,并在bool Querymust_not子句中创建与AvailableTo AvailableTo查询的分离,即反转存在的文档。

如下所示(我已经注释掉了未提供的查询)

代码语言:javascript
复制
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))
);

这将产生以下查询

代码语言:javascript
复制
{
  "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子句

代码语言:javascript
复制
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))
);

创建查询的

代码语言:javascript
复制
{
  "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查询。

票数 3
EN

Stack Overflow用户

发布于 2018-11-14 16:42:27

好吧,我想我已经研究过了。我取出了“必须日期”范围,并将其设为“应该”,所以现在的查询如下:

代码语言:javascript
复制
 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日期集的日期和匹配的范围内返回结果。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53304062

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档