简体   繁体   English

C# NEST 中的动态弹性搜索查询

[英]Dynamic Elastic search query in c# NEST

Started working on NEST api for elastic search recently, got stuck on following query, the data.e would be dynamically populated using the input from client in the HttpGet, ex: user sends eventA,eventB,eventC then we would add in the should part:最近开始使用 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": {} 
        }}
      ]
    }
  }
}

Following is what I came up with till now:以下是我到现在为止想出来的:

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?
                                    )
                                    )
                                )
                        )
                    )
                ));

Can someone please help how to build the should part dynamically based on what input the user sends?有人可以帮助如何根据用户发送的输入动态构建should部分吗?

Thanks.谢谢。

You can replace the nested query in the above snippet as shown below您可以替换上面代码段中的嵌套查询,如下所示

// 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]))));
}

What we are essentially doing here is we are returning a QueryContainer object that will be passed to the nested query我们实际上在这里做的是返回一个QueryContainer对象,该对象将传递给嵌套查询

.Query(q => Blah(<your parameters>))

The same can be done by adding this inline without a separate method.可以通过添加此内联而不使用单独的方法来完成相同的操作。 You may choose which ever route you perfer.您可以选择您喜欢的路线。 However, in general, having a method of its own increases the readability and keeps things cleaner.然而,一般来说,拥有自己的方法会增加可读性并使事情更清晰。

You can read more about Match usage here您可以在此处阅读有关Match用法的更多信息

Edit:编辑:

Since you want to dynamically add the match queries inside this, below is a way you can do it.由于您想在其中动态添加匹配查询,因此您可以通过以下方式进行操作。

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();
}

Now, call this method from inside of the above method as shown below现在,从上面的方法内部调用这个方法,如下所示

public static QueryContainer Blah(params string[] param)
{
    return new QueryContainerDescriptor<Events>().Bool(
        b => b.Should(
            InnerBlah("field", param)));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM