c# NEST 中的动态弹性搜索查询
Dynamic Elastic search query in c# NEST
最近开始使用 NEST api 进行弹性搜索,卡在以下查询中,data.e 将使用 HttpGet 中客户端的输入动态填充,
例如:用户发送 eventA、eventB、eventC 然后我们将在应该部分添加:
GET events/_search
{
"_source": false,
"query": {
"bool": {
"must": [
{"range": {
"timestamp": {
"gte": 1604684158527,
"lte": 1604684958731
}
}},
{"nested": {
"path": "data",
"query": {
"bool": {
"should": [
{"match": {
"data.e": "eventA"
}},
{"match": {
"data.e": "eventB"
}},
{"match": {
"data.e": "eventC"
}},
]
}
},
"inner_hits": {}
}}
]
}
}
}
以下是我到目前为止的想法:
var graphDataSearch = _esClient.Search<Events>(s => s
.Source(src => src
.Includes(i => i
.Field("timestamp")
)
)
.Query(q => q
.Bool(b => b
.Must(m => m
.Range(r => r
.Field("timestamp")
.GreaterThanOrEquals(startTime)
.LessThanOrEquals(stopTime)
),
m => m
.Nested(n => n
.Path("data")
.Query(q => q
.Bool(bo => bo
.Should(
// what to add here?
)
)
)
)
)
));
有人可以帮助如何根据用户发送的输入动态构建 should
部分吗?
谢谢。
您可以替换上面代码段中的嵌套查询,如下所示
// You may modify the parameters of this method as per your needs to reflect user input
// Field can be hardcoded as shown here or can be fetched from Event type as below
// m.Field(f => f.Data.e)
public static QueryContainer Blah(params string[] param)
{
return new QueryContainerDescriptor<Events>().Bool(
b => b.Should(
s => s.Match(m => m.Field("field1").Query(param[0])),
s => s.Match(m => m.Field("field2").Query(param[1])),
s => s.Match(m => m.Field("field3").Query(param[2]))));
}
我们实际上在这里做的是返回一个 QueryContainer
对象,该对象将传递给嵌套查询
.Query(q => Blah(<your parameters>))
无需单独的方法即可通过添加此内联来完成相同的操作。您可以选择自己喜欢的路线。但是,总的来说,拥有自己的方法会增加可读性并使事情更清晰。
您可以阅读更多关于 Match
用法的信息 here
编辑:
既然你想在其中动态添加匹配查询,下面是你可以做到的方法。
private static QueryContainer[] InnerBlah(string field, string[] param)
{
QueryContainer orQuery = null;
List<QueryContainer> queryContainerList = new List<QueryContainer>();
foreach (var item in param)
{
orQuery = new MatchQuery() {Field = field, Query = item};
queryContainerList.Add(orQuery);
}
return queryContainerList.ToArray();
}
现在,从上面的方法内部调用这个方法,如下所示
public static QueryContainer Blah(params string[] param)
{
return new QueryContainerDescriptor<Events>().Bool(
b => b.Should(
InnerBlah("field", param)));
}
最近开始使用 NEST api 进行弹性搜索,卡在以下查询中,data.e 将使用 HttpGet 中客户端的输入动态填充, 例如:用户发送 eventA、eventB、eventC 然后我们将在应该部分添加:
GET events/_search
{
"_source": false,
"query": {
"bool": {
"must": [
{"range": {
"timestamp": {
"gte": 1604684158527,
"lte": 1604684958731
}
}},
{"nested": {
"path": "data",
"query": {
"bool": {
"should": [
{"match": {
"data.e": "eventA"
}},
{"match": {
"data.e": "eventB"
}},
{"match": {
"data.e": "eventC"
}},
]
}
},
"inner_hits": {}
}}
]
}
}
}
以下是我到目前为止的想法:
var graphDataSearch = _esClient.Search<Events>(s => s
.Source(src => src
.Includes(i => i
.Field("timestamp")
)
)
.Query(q => q
.Bool(b => b
.Must(m => m
.Range(r => r
.Field("timestamp")
.GreaterThanOrEquals(startTime)
.LessThanOrEquals(stopTime)
),
m => m
.Nested(n => n
.Path("data")
.Query(q => q
.Bool(bo => bo
.Should(
// what to add here?
)
)
)
)
)
));
有人可以帮助如何根据用户发送的输入动态构建 should
部分吗?
谢谢。
您可以替换上面代码段中的嵌套查询,如下所示
// You may modify the parameters of this method as per your needs to reflect user input
// Field can be hardcoded as shown here or can be fetched from Event type as below
// m.Field(f => f.Data.e)
public static QueryContainer Blah(params string[] param)
{
return new QueryContainerDescriptor<Events>().Bool(
b => b.Should(
s => s.Match(m => m.Field("field1").Query(param[0])),
s => s.Match(m => m.Field("field2").Query(param[1])),
s => s.Match(m => m.Field("field3").Query(param[2]))));
}
我们实际上在这里做的是返回一个 QueryContainer
对象,该对象将传递给嵌套查询
.Query(q => Blah(<your parameters>))
无需单独的方法即可通过添加此内联来完成相同的操作。您可以选择自己喜欢的路线。但是,总的来说,拥有自己的方法会增加可读性并使事情更清晰。
您可以阅读更多关于 Match
用法的信息 here
编辑:
既然你想在其中动态添加匹配查询,下面是你可以做到的方法。
private static QueryContainer[] InnerBlah(string field, string[] param)
{
QueryContainer orQuery = null;
List<QueryContainer> queryContainerList = new List<QueryContainer>();
foreach (var item in param)
{
orQuery = new MatchQuery() {Field = field, Query = item};
queryContainerList.Add(orQuery);
}
return queryContainerList.ToArray();
}
现在,从上面的方法内部调用这个方法,如下所示
public static QueryContainer Blah(params string[] param)
{
return new QueryContainerDescriptor<Events>().Bool(
b => b.Should(
InnerBlah("field", param)));
}