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

时间:2015-08-31 02:14:44

标签: c# elasticsearch asp.net-web-api2 nest

背景/目标

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

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

查询,用简单的英语

我们有几个字段的过滤器。每个内部过滤器都是一个或过滤器,但它们一起作为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
}

1 个答案:

答案 0 :(得分:2)

这种任务在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的最佳选择,因为它专为简单和简单而设计。易于使用的目的。我只使用较低的API,如果我想使用Nest当时不支持的新功能,或者Nest在我使用的函数中有bug。 您可以在这里参考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()))

希望有所帮助