【问题标题】:Multiple exclusive OR filter in a bool Query布尔查询中的多个异或过滤器
【发布时间】:2016-06-28 19:57:01
【问题描述】:

在 Nest 的早期版本中,即 1.x 中允许多个独占或过滤器,如下面的原始查询

在 2.x 中不再推荐使用 AS orFilters 来替代它。如何在 Bool 查询中拥有多个独占应该(或过滤器)以及必须?

来自 1.x 的原始查询

  {
       "bool": {
         "must": [
           {
             "bool": {
               "must": [
                 {
                   "term": {
                     "EntityType": "ITSTrucks"
                   }
                 },
                 {
                   "or": {
                     "filters": [
                       {
                         "term": {
                           "AvailableDate": 36523
                         }
                       },
                       {
                         "range": {
                           "AvailableDate": {
                             "gte": "42036"
                           }
                         }
                       }
                     ],
                     "_name": "date"
                   }
                 },
                 {
                   "or": {
                     "filters": [
                       {
                         "geo_distance": {
                           "OriginCoordinate": "42.815656,-73.942324",
                           "distance": "100miles",
                           "distance_type": "plane"
                         }
                       }
                     ],
                     "_name": "OriginOrFilter"
                   }
                 },
                 {
                   "or": {
                     "filters": [
                       {
                         "term": {
                           "IsOpen": true
                         }
                       },
                       {
                         "term": {
                           "IsDestinationBoundaryNull": true
                         }
                       }
                     ],
                     "_name": "DestinationOrFilter"
                   }
                 }
               ]
             }
           }
         ]
       }
     }

会这样吗?

    BoolQueryDescriptor<AvailableTrucks>  queryParameterMust= new BoolQueryDescriptor<AvailableTrucks>();
    BoolQueryDescriptor<AvailableTrucks> queryParameterShouldFirst= new BoolQueryDescriptor<AvailableTrucks>();
    BoolQueryDescriptor<AvailableTrucks> queryParameterShouldSecond= new BoolQueryDescriptor<AvailableTrucks>();
    BoolQueryDescriptor<AvailableTrucks> queryParameterShouldThird= new BoolQueryDescriptor<AvailableTrucks>();
    if (mustfc.Count > 0)
    {
        queryParameterMust.Must(mustfc.ToArray());
    }
    if (shouldQueryListFirst.Count > 0)
    {
        queryParameterShouldFirst.Should(shouldQueryListFirst.ToArray());
    }
    if (ShouldQueryListSecond.Count > 0)
    {
        queryParameterShouldSecond.Should(ShouldQueryListSecond.ToArray());
    }
    if (ShouldQueryListThird.Count > 0)
    {
        queryParameterShouldThird.Should(ShouldQueryListThird.ToArray());
    }
elasticClient.Search<Truck>(s => s.Query(f => f.Bool(c => c.Must(u => u.MatchAll()).Filter(q => q.Bool(b => queryParameterMust && queryParameterShouldFirst && queryParameterShouldSecond && queryParameterShouldThird)))))>Index("Trucks")

【问题讨论】:

  • 我不知道 elasticsearch 中的 EXOR 能力,但你有 AND(必须)、OR(应该)和 NOT(must_not),所以你可以自己做 EXOR。 a EXOR b == (a AND NOT b) OR (b AND NOT a)

标签: elasticsearch nest


【解决方案1】:

在 2.x.x 版本中,您可以使用 Should 术语进行逻辑 OR 查询。

一些例子:

{
    "bool" : {
        "must" : {
            "term" : { "user" : "kimchy" }
        }
        "should" : [
            {
                "term" : { "tag" : "wow" }
            },
            {
                "term" : { "tag" : "elasticsearch" }
            }
        ],
        "minimum_should_match" : 1
    }
}

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html

请注意,您也可以嵌套这些术语。

要使用 NEST 构建查询,您可以尝试:

var mustMatchQueries = new List<QueryContainer>()
var shouldMatchQueries = new List<QueryContainer>();

// ... add queries to both lists

// aggregate queries
var mustMatchAggregatedTerms = mustMatchQueries.Aggregate(new QueryContainer(), (s, ff) => s &= ff);
var shouldMatchAggregatedTerms = shouldMatchQueries.Aggregate(new QueryContainer(), (s, ff) => s |= ff);

// build descriptor
var descriptor = new SearchDescriptor<DocumentClassName>()
descriptor.Query(q => q.Bool(b => b.Must(m => mustMatchAggregatedTerms && m.Bool(c => c.Should(shouldMatchAggregatedTerms)))));

【讨论】:

  • should 在查询上下文和过滤上下文中的行为不同。我认为 OP 希望它在过滤器上下文中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多