【问题标题】:Dynamic Elastic search query in c# NESTc# NEST 中的动态弹性搜索查询
【发布时间】:2021-03-02 07:14:39
【问题描述】:

最近开始使用 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 部分吗?

谢谢。

【问题讨论】:

    标签: c# asp.net elasticsearch .net-core nest


    【解决方案1】:

    可以替换上面sn -p中的嵌套查询如下图

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

    【讨论】:

    • should() 中的部分,需要动态创建,用户可以发送 4 个事件或 5 个事件,所以我们也必须匹配它们,您发布的解决方案是硬编码的 3 类型参数仅作为示例显示。
    • 您可以遍历发送的项目并在should 中生成内部匹配查询。将编辑答案以提供有关如何操作的指示
    • @Ghanendra - 为多个匹配查询添加了动态生成逻辑
    • 感谢您的帮助!我不得不将您的代码修改为以下 private QueryContainer[] InnerBlah(string field, List&lt;string&gt; param) { QueryContainer orQuery = null; List&lt;QueryContainer&gt; lq = new List&lt;QueryContainer&gt;(); foreach (string item in param) { orQuery = new MatchQuery() { Field = field, Query = item }; lq.Add(orQuery); } return lq.ToArray(); } ,否则它会创建多个 should[bool( 请求 json 中的元素
    • @Ghanendra - 啊!诚然。我已经修改了答案以反映变化。干杯!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-17
    • 1970-01-01
    • 1970-01-01
    • 2018-11-09
    • 2017-02-24
    • 1970-01-01
    相关资源
    最近更新 更多