【问题标题】:Need help implementing multiple Or conditions in Nest query需要帮助在 Nest 查询中实现多个 Or 条件
【发布时间】:2015-09-30 08:08:19
【问题描述】:

我正在尝试在 Nest ElasticSearch 中实现以下 SQL 伪代码。

我没有找到任何与此问题或 Nest 文档相匹配的类似 StackOverflow 问题。感谢您提供的任何方向。

select * 
from curator..published
where accountId = 10
  and ( 
        (publishStatusId = 3 and scheduledDT > '2015-09-01')
        or
        (publishStatusId = 4 and publishedDT > '2015-09-01')
      )

我创建了以下 ElasticSearch 查询,但无法成功将其转换为 Nest 语法。

GET curator/published/_search
{
  "query": {
    "filtered": {
      "filter": {
        "bool": {
          "must": [
            {
              "term": {
                "accountID": 1781
              }
            }
          ],
          "should": [
            {
              "bool": {
                "must": [
                  {
                    "term": {
                      "publishStatusID": 4
                    }
                  },
                  {
                    "range": {
                      "publishedDT": {
                        "gte": "2015-09-01T00:00:00.000"
                      }
                    }
                  }
                ]
              }
            },
            {
              "bool": {
                "must": [
                  {
                    "term": {
                      "publishStatusID": 3
                    }
                  },
                  {
                    "range": {
                      "scheduleDT": {
                        "gte": "2015-09-01T00:00:00.000"
                      }
                    }
                  }
                ]
              }
            }
          ]
        }
      }
    }
  }
}

此 Nest 查询通过了语法检查,但只有最后一个“应该”条件出现在生成的 ElasticSearch 查询中。

var results = this.Client.Count<Data>(c => c
    .Query(q => q
        .Filtered(f1 => f1
            .Filter(f2 => f2
                .Bool(b => b
                    .Must(
                        f => f.Term(FieldName.AccountID, "10")
                    )
                    .Should(s => s
                        .Bool(b1 => b1
                            .Must(
                                f => f.Term(FieldName.PublishStatusID, "3"),
                                f => f.Range(m => m.OnField(FieldName.ScheduleDT).GreaterOrEquals("2015-09-01"))
                            )
                        )
                    )
                    .Should(s => s
                        .Bool(b1 => b1
                            .Must(
                                f => f.Term(FieldName.PublishStatusID, "4"),
                                f => f.Range(m => m.OnField(FieldName.PublishedDT).GreaterOrEquals("2015-09-01"))
                            )
                        )
                    )
                )
            )
        )
    )
);

此 Nest 查询更好地匹配原始 ElasticSearch 查询,但在 2nd Bool 上引发以下错误:错误 51 'Nest.FilterContainer' 不包含 'Bool' 的定义并且没有扩展方法 'Bool' 接受第一个参数可以找到类型“Nest.FilterContainer”(您是否缺少 using 指令或程序集引用?)

var results = this.Client.Count<Data>(c => c
    .Query(q => q
        .Filtered(f1 => f1
            .Filter(f2 => f2
                .Bool(b => b
                    .Must(
                        f => f.Term(FieldName.AccountID, AccountID)
                    )
                    .Should(s => s
                        .Bool(b1 => b1
                            .Must(
                                f => f.Term(FieldName.PublishStatusID, "3"),
                                f => f.Range(m => m.OnField(FieldName.ScheduleDT).GreaterOrEquals("2015-09-01"))
                            )
                        )
                        .Bool(b2 => b2
                            .Must(
                                f => f.Term(FieldName.PublishStatusID, "4"),
                                f => f.Range(m => m.OnField(FieldName.PublishedDT).GreaterOrEquals("2015-09-01"))
                            )
                        )
                    )
                )
            )
        )
    )
);    

【问题讨论】:

    标签: c# elasticsearch nest


    【解决方案1】:

    您的第一个查询并不遥远,只是传递给第二个Should() 的表达式需要是另一个传递给第一个Should() 的表达式(Should() 需要一个params Func[] filters)。这是查询(我在这里使用dynamic 作为通用类型):

    void Main()
    {
        var settings = new ConnectionSettings(new Uri("http://localhost:9200"));
        var connection = new InMemoryConnection(settings);
        var client = new ElasticClient(connection: connection);
    
        var docs = client.Count<dynamic>(c => c
            .Query(q => q
                .Filtered(f1 => f1
                    .Filter(f2 => f2
                        .Bool(b => b
                            .Must(
                                f => f.Term(FieldName.AccountID, "10")
                            )
                            .Should(s => s
                                .Bool(b1 => b1
                                    .Must(
                                        f => f.Term(FieldName.PublishStatusID, "3"),
                                        f => f.Range(m => m.OnField(FieldName.ScheduleDT).GreaterOrEquals("2015-09-01"))
                                    )
                                ),
                                    s => s
                                .Bool(b1 => b1
                                    .Must(
                                        f => f.Term(FieldName.PublishStatusID, "4"),
                                        f => f.Range(m => m.OnField(FieldName.PublishedDT).GreaterOrEquals("2015-09-01"))
                                    )
                                )
                            )
                        )
                    )
                )
            )
        );
    
        Console.WriteLine(Encoding.UTF8.GetString(docs.RequestInformation.Request));
    }
    
    public static class FieldName
    {
        public static string AccountID = "AccountID";
        public static string ScheduleDT = "ScheduleDT";
        public static string PublishedDT = "PublishedDT";
        public static string PublishStatusID = "PublishStatusID";
    }
    

    生产

    {
      "query": {
        "filtered": {
          "filter": {
            "bool": {
              "must": [
                {
                  "term": {
                    "AccountID": "10"
                  }
                }
              ],
              "should": [
                {
                  "bool": {
                    "must": [
                      {
                        "term": {
                          "PublishStatusID": "3"
                        }
                      },
                      {
                        "range": {
                          "ScheduleDT": {
                            "gte": "2015-09-01"
                          }
                        }
                      }
                    ]
                  }
                },
                {
                  "bool": {
                    "must": [
                      {
                        "term": {
                          "PublishStatusID": "4"
                        }
                      },
                      {
                        "range": {
                          "PublishedDT": {
                            "gte": "2015-09-01"
                          }
                        }
                      }
                    ]
                  }
                }
              ]
            }
          }
        }
      }
    }
    

    这与您上面的查询 DSL 匹配

    【讨论】:

    • 非常感谢拉斯!这很有道理。
    • @ShawnMac - 不用担心,很乐意提供帮助
    猜你喜欢
    • 1970-01-01
    • 2012-05-09
    • 2017-08-31
    • 2012-02-04
    • 2011-03-08
    • 1970-01-01
    • 2011-08-06
    • 1970-01-01
    • 2023-03-15
    相关资源
    最近更新 更多