匹配术语列表中至少一个术语的正确方法

时间:2018-10-26 17:01:48

标签: elasticsearch nest

我需要匹配一个字段的列表,以查看另一个列表中是否至少有一个术语。换句话说,我的Es存储项目具有适合的“类别”列表。我需要向上传递要包括在搜索中的类别列表。我想从搜索中包括的类别列表中获取其类别列表中一个或多个类别的所有项目。

我发现这段代码可以实现我想要的功能

...
  .Must(qs => qs
    .TermsSet(t => t
      .Field(tf => tf.categories)
      .Terms(searchCategories)
      .MinimumShouldMatchScript(ss => ss.Source("1"))
    )
  )
...

但是,将脚本“ 1”放入其中似乎真的很奇怪。感觉我可能缺少一种更简单的方法来实现这一目标。我的怀疑正确吗?有更好的方法吗?

更新

上面的代码产生了这个es请求:

...
  "must":[
    {
      "terms_set":{
        "categories":{
          "terms":[1],
          "minimum_should_match_script":{"source":"1"}
        }
      }
    }
  ]
...

termssearchCategories列表的地方

1 个答案:

答案 0 :(得分:1)

"1"的来源指定为terms set query的最小匹配脚本字段,这将是执行的Painless script的返回值,该值确定应匹配的最小术语数。与每个文档返回单个值相比,该脚本当然会更复杂,从而使您可以针对attribute based access control等用例提出更复杂的匹配要求。

如果您只需要匹配提供的术语列表中的任何一个术语,则只需使用terms query

var searchCategories = new [] {1 };

var searchResponse = client.Search<MyDocument>(s => s
    .Query(q => +q
        .Terms(t => t
            .Field(f => f.categories)
            .Terms(searchCategories)
        )
    )
);

会产生

{
  "query": {
    "bool": {
      "filter": [
        {
          "terms": {
            "categories": [
              1
            ]
          }
        }
      ]
    }
  }
}

查询中的unary + overloaded operator是NEST的一项功能,使编写布尔查询更为简洁。