我如何使用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
}
标题>
这类任务在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,…)的更多信息。
更新:动态创建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()))
希望能有所帮助