如何使用 NEST 准确表示此 ElasticSearch 查询?

How do I accurately represent this ElasticSearch query using NEST?

背景/目标

我在 ElasticSearch 中有一个查询,我在几个字段上使用过滤器(相对较小的数据集,我们在查询时确切地知道这些字段中应该有什么值)。我们的想法是,我们将执行全文查询,但仅在我们过滤了用户所做的一些选择之后。

我将 ElasticSearch 置于 WebAPI 控制器之后,并认为使用 NEST 来完成查询是有意义的。

查询,用简单的英语

我们有多个字段的过滤器。每个内部筛选器都是一个或筛选器,​​但它们一起作为一个 AND。

在SQL中,等效的伪代码是select * from table where foo in (1,2,3) AND bar in (4,5,6)

问题

查询文本

{
  "query": {
    "filtered": {
      "filter": {
        "bool": {
          "must": [
            {
              "or": [
                { "term": { "foo": "something" } },
                { "term": { "foo": "somethingElse" } }
              ]
            },
            {
              "or": [
                { "term": { "bar": "something" } },
                { "term": { "bar": "somethingElse" } }
              ]
            }
          ]
        }
      }
    }
  },

  "size": 100
}

这种任务在ES中比较简单,也很流行。 您可以在 NEST 中表示它,如下所示:

var rs = es.Search<dynamic>(s => s
            .Index("your_index").Type("your_type")
            .From(0).Size(100)
            .Query(q => q
                .Filtered(fq => fq
                    .Filter(ff => ff
                        .Bool(b => b
                            .Must(
                                m1 => m1.Terms("foo", new string[] { "something", "somethingElse" }),
                                m2 => m2.Terms("bar", new string[] { "something", "somethingElse" })
                            )
                        )
                    )
                    .Query(qq => qq
                        .MatchAll()
                    )
                )
            )
        );

一些注意事项:

  • 我使用过滤查询先过滤我需要的东西,然后再搜索东西。在这种情况下,它将筛选 foo in ("something", "somethingElse") AND bar in ("something", "somethingElse"),然后查询所有筛选结果 (match_all)。您可以将 match_all 更改为您需要的内容。 filtered query 这是为了获得最佳性能,因为 ES 只需要评估 query 部分(过滤后)中的文档分数,而不是所有文档。
  • 我使用terms过滤器,比or更简单,性能更好。 terms 的默认模式是 OR 所有输入项,您可以参考文档中有关可用模式(AND、OR、PLAIN、...)的更多信息。

在我看来,Nest 是 .NET 的最佳选择,因为它旨在简单易用。如果我想使用当时 Nest 不支持的新功能,或者 Nest 在我使用的功能中存在错误,我只使用较低的 API。 你可以在这里参考一个简短的 NEST 教程:http://nest.azurewebsites.net/nest/writing-queries.html

更新:构建布尔过滤器动态:

var filters = new List<Nest.FilterContainer>();
filters.Add(Nest.Filter<dynamic>.Terms("foo", new string[] { "something", "somethingElse" }));
// ... more filter

然后将 .Bool(b => b.Must(...)) 替换为 .Bool(b => b.Must(filters.ToArray()))

希望对您有所帮助