c#NEST中的动态弹性搜索查询
最近开始为elastic search开发NEST api,在下面的查询中遇到问题,数据.e将使用HttpGet中客户端的输入动态填充, 例如:用户发送eventA、eventB、eventC,然后我们将添加should部分:c#NEST中的动态弹性搜索查询,c#,asp.net,elasticsearch,.net-core,nest,C#,Asp.net,elasticsearch,.net Core,Nest,最近开始为elastic search开发NEST api,在下面的查询中遇到问题,数据.e将使用HttpGet中客户端的输入动态填充, 例如:用户发送eventA、eventB、eventC,然后我们将添加should部分: GET events/_search { "_source": false, "query": { "bool": { "must": [ {&q
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?
)
)
)
)
)
));
var graphDataSearch=\u esClient.Search(s=>s
.Source(src=>src
.包括(i=>i
.Field(“时间戳”)
)
)
.Query(q=>q
.Bool(b=>b
.Must(m=>m
.范围(r=>r
.Field(“时间戳”)
.GreaterThanOrEquals(开始时间)
.LessThanOrEquals(停车时间)
),
m=>m
.Nested(n=>n
.Path(“数据”)
.Query(q=>q
.Bool(bo=>bo
.应该(
//这里要补充什么?
)
)
)
)
)
));
是否有人可以帮助您根据用户发送的输入动态构建应该部分
谢谢。您可以替换上面代码段中的嵌套查询,如下所示
// 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]))));
}
public static QueryContainer Blah(params string[] param)
{
return new QueryContainerDescriptor<Events>().Bool(
b => b.Should(
InnerBlah("field", param)));
}
通过添加此内联而不使用单独的方法也可以做到这一点。您可以选择您喜欢的路由。但是,一般来说,拥有自己的方法可以增加可读性并保持更干净
您可以阅读有关Match
用法的更多信息
编辑:
由于您希望在其中动态添加匹配查询,下面是一种方法
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();
}
private static QueryContainer[]InnerBlah(字符串字段,字符串[]参数)
{
QueryContainer或query=null;
List queryContainerList=新列表();
foreach(参数中的变量项)
{
orQuery=new MatchQuery(){Field=Field,Query=item};
queryContainerList.Add(或query);
}
返回queryContainerList.ToArray();
}
现在,从上述方法的内部调用此方法,如下所示
// 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]))));
}
public static QueryContainer Blah(params string[] param)
{
return new QueryContainerDescriptor<Events>().Bool(
b => b.Should(
InnerBlah("field", param)));
}
公共静态查询容器Blah(params string[]param)
{
返回新的QueryContainerDescriptor().Bool(
b=>b.应该(
InnerBlah(“字段”,参数));
}
should()内的零件,需要动态创建,用户可以发送4个事件或5个事件,因此我们也必须匹配它们,您发布的解决方案仅针对3种类型的参数进行硬编码,我将其作为示例显示。您可以循环发送的项目,并在should
内部生成内部匹配查询。将编辑答案以提供指针怎么办it@Ghanendra-为多个匹配查询添加了动态生成逻辑感谢您的帮助!我不得不将您的代码稍微修改为以下private QueryContainer[]InnerBlah(字符串字段,列表参数){QueryContainer orQuery=null;List lq=new List();foreach(参数中的字符串项){orQuery=new MatchQuery(){Field=Field,Query=item};lq.Add(orQuery);}返回lq.ToArray();}
,否则它将创建多个shoul[bool](b)请求中的要素json@Ghanendra-啊!没错。我修改了答案以反映变化。干杯!