【问题标题】:Elasticsearch nested query with available values in range具有范围内可用值的 Elasticsearch 嵌套查询
【发布时间】:2021-03-01 02:40:18
【问题描述】:

尝试为以下文档构建查询:

{
    "name" : "Bob",
    "grades" : [
        {
            "year" : 2010,
            "grade": 8,  
        },
        {
            "year" : 2018,
            "grade": 7,  
        },
        {
            "year" : 2019,
            "grade": 4,  
        }
    ]
},
{
    "name" : "Alice",
    "grades" : [
        { 
            "year" : 2005,
            "grade": 3,  
        },
        {
            "year" : 2016,
            "grade": 8,  
        },
        {
            "year" : 2018,
            "grade": 7,  
        },
        {
            "year" : 2019,
            "grade": 6,  
        }
    ]
}

我有一系列年份,例如从 2010 年到 2020 年。如果在(从 2010 年到 2020 年)范围内的所有可用年份(在文档中),等级 > 5,则查询应该返回一个文档。如果在感兴趣的年份范围之外有等级

{
    "query": {
        "bool": {
            "must": [
                {
                    "nested": {
                        "query": {
                            "bool": {
                                "must": [
                                    {
                                        "term": {
                                            "grades.year": {"value": 2010}
                                        }
                                    },
                                    {
                                        "range": {
                                            "grades.grade": {"from": 5}
                                        }
                                    }
                                ]
                            }
                        },
                        "path": "grades"
                    }
                },
                {
                    "nested": {
                        "query": {
                            "bool": {
                                "must": [
                                    {
                                        "term": {
                                            "grades.year": {"value": 2011}
                                        }
                                    },
                                    {
                                        "range": {
                                            "grades.grade": {"from": 5}
                                        }
                                    }
                                ]
                            }
                        },
                        "path": "grades"
                    }
                },
                ....
            ]
        }
    }
}

可能我肯定错过了什么。有可能吗?

更新

我在 Alice 的成绩中添加了 2005 年的 3 年级。所以现在 Alice 仍然应该匹配,因为 2005 年超出了感兴趣的范围。

谢谢!

【问题讨论】:

    标签: elasticsearch elasticsearch-5 elasticsearch-dsl


    【解决方案1】:

    您可以使用must_not 子句,这将排除所有等级小于或等于5的文档

    搜索查询:

    {
      "query": {
        "bool": {
          "must": [
            {
              "nested": {
                "path": "grades",
                "query": {
                  "bool": {
                    "must": [
                      {
                        "range": {
                          "grades.year": {
                            "gte": 2010,
                            "lte": 2020
                          }
                        }
                      }
                    ]
                  }
                }
              }
            }
          ],
          "must_not": {
            "nested": {
              "path": "grades",
              "query": {
                "bool": {
                  "must": [
                    {
                      "range": {
                        "grades.grade": {
                          "lte": 5
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      }
    }
    

    搜索结果:

    "hits": [
          {
            "_index": "64882747",
            "_type": "_doc",
            "_id": "2",
            "_score": 1.0,
            "_source": {
              "name": "Alice",
              "grades": [
                {
                  "year": 2016,
                  "grade": 8
                },
                {
                  "year": 2018,
                  "grade": 7
                },
                {
                  "year": 2019,
                  "grade": 6
                }
              ]
            }
          }
        ]
    

    【讨论】:

    • 谢谢!这真的很有帮助,几乎可以满足我的需要。但显然,如果至少一年有 lte 5 级,它会丢弃文件。如果有一年不在感兴趣的范围内,我们不应该关心等级是否是 lte 5。我已经更新了我的问题。谢谢!
    • @Zanas_x3 但年份2005 超出范围,grade 也小于5,但您仍然希望Alice 文档匹配?
    • 就是这样。我们只对 [2010, 2020] 范围内的成绩感兴趣。如果很久以前成绩低于5,我们真的不在乎。我将编辑我的问题以使其更清楚,抱歉造成混淆。谢谢!
    • @Zanas_x3 感谢您的回复 :) 让我看看能否找到实现您的用例的方法
    • 感谢 Bhavya!您通过指导正确的路径帮助了我。看看我的解决方案,看起来它应该做的。希望...
    【解决方案2】:

    看来我找到了解决方案!感谢@Bhavya 指导我。基本上有一些额外的布尔逻辑。我最终得到以下查询:

    {
        "query": {
            "bool": {
                "must": [
                    {
                        "nested": {
                            "path": "grades",
                            "query": {
                                "bool": {
                                    "must": [
                                        {
                                            "range": {
                                                "grades.year": {
                                                    "gte": 2010,
                                                    "lte": 2020
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                ],
                "must_not":   {
                    "nested": {
                        "path": "grades",
                        "query": {
                            "bool": {
                                "should": [
                                    {
                                        "bool": {
                                            "must": [
                                                {
                                                    "term": {
                                                        "grades.year": {
                                                            "value": 2010
                                                        }
                                                    }
                                                },
                                                {
                                                    "range": {
                                                        "grades.grade": {
                                                            "lte": 5
                                                        }
                                                    }
                                                }
                                            ]
                                        }
                                    },
                                    ...
                                    ...
                                    ...
                                    ...
                                    ...
                                ]
                            }
                        }
                    }
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-05-20
      • 1970-01-01
      • 2017-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-07
      • 2015-12-25
      • 1970-01-01
      相关资源
      最近更新 更多