我如何使用NEST准确地表示这个ElasticSearch查询

本文关键字:表示 ElasticSearch 查询 地表 何使用 NEST | 更新日期: 2023-09-27 18:10:31

背景/目标

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

我把ElasticSearch放在WebAPI控制器后面,并认为使用NEST来完成查询是有意义的。

查询,用简单的英语表示

我们有几个字段的过滤器。每个内部过滤器都是一个or过滤器,但它们在一起是一个AND。

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

<标题>
  • 我可以简化我思考这个查询的方式,基于你在下面看到的?我是不是忽略了一些基本的方法?这看起来很重,但我是ES的新手。
  • 我如何在NEST语法中正确地表示下面的查询?
  • NEST是最好的选择吗?我应该使用ElasticSearch库,而不是去更低的水平?

查询文本

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

我如何使用NEST准确地表示这个ElasticSearch查询

这类任务在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在我使用的函数中有bug,我只会使用较低的API。你可以在这里参考一个简短的NEST教程:http://nest.azurewebsites.net/nest/writing-queries.html

更新:动态创建bool过滤器:

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()))

希望能有所帮助