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

Proper way to match at least 1 term from a list of terms

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

我发现这段代码符合我的要求:

...
  .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 列表

terms set query minimum should match script field will be the return value of the executed Painless script that determines the minimum number of terms that should match. The script can of course be more complex than returning a single value per document, allowing you to come up with more complex matching requirements for use cases such as attribute based access control.

指定 "1" 的来源

如果您只需要 任何一个 提供的术语列表中的术语进行匹配,那么您可以简单地使用 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 的一项功能,它使编写 bool 查询更加简洁。