Elasticsearch 嵌套查询,可用值在范围内

Elasticsearch nested query with available values in range

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

{
    "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,则查询应该 return 一个文档。如果在感兴趣的年份范围之外有 <= 5 的等级,我们不在乎,这些不应该以任何方式影响最终结果。所以基本上只有 Alice 的文档应该被 returned。查看 Elasticsearch 文档后,找不到解决方案(很可能我只是错过了一些东西)。如果几年之间没有差距,我可以构建一个查询,但就我而言,存在差距。所以我的查询只是删除了这些文件。当前查询:

{
    "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"
                    }
                },
                ....
            ]
        }
    }
}

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

更新

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

谢谢!

您可以使用 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
            }
          ]
        }
      }
    ]

看来我找到了解决办法!感谢@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
                                                    }
                                                }
                                            }
                                        ]
                                    }
                                },
                                ...
                                ...
                                ...
                                ...
                                ...
                            ]
                        }
                    }
                }
            }
        }
    }
}