如何使用 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)
。
问题
- 我可以根据您在下面看到的内容简化我考虑此查询的方式吗?我是否忽略了一些基本方法?这看起来很重,但我是 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、...)的更多信息。
在我看来,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()))
希望对您有所帮助
背景/目标
我在 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
}
这种任务在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()))
希望对您有所帮助