当前位置: 首页 > 知识库问答 >
问题:

ElasticSearch按深度嵌套排序/评分

袁桐
2023-03-14

我的索引中有以下类型的文档,但由于深度嵌套方面,我找不到正确排序的方法。

文档示例:

{
  "metadatas": [{
    "name": "name",
    "timeValidity": [{
      "since": "1970-01-01T00:00:00.000Z",
      "until": "2100-01-01T00:00:00.000Z",
      "value_s": "Some random name"
    }]
  }, {
    "name": "riskRatio",
    "variants": [{
      "value": "3Y",
      "timeValidity": [{
        "since": "2017-11-17T23:59:59.999Z",
        "until": "2017-12-01T23:59:59.998Z",
        "value_f": 0.6931
      }, {
        "since": "2017-12-01T23:59:59.999Z",
        "until": "2018-03-01T23:59:59.999Z",
        "value_f": 0.7215
      }, {
        "since": "2018-04-12T00:00:00.000Z",
        "until": "2018-04-16T23:59:59.999Z",
        "value_f": 0.6849
      }]
    }]
  }]
}

我希望排序或提升在匹配时间,以便我可以得到排序的文档metadatas.variants.timeValidity.value_f(asc/desc)与约束metadata.name=riskRatio和内嵌套文档metadata.variants.value=3Y和内嵌套文档metadata.variants.timeValidity.since

过滤结果正常。我的问题在于事物的分类方面。

script\u score似乎需要指定一个访问键,这是不可能的,因为我不知道数组中的位置<代码>排序不允许我过滤两个属性的范围,因此它也是一条死胡同。所以我最后一次失败的尝试是从下往上走,就像这样:

{
  "sort": [{
    "metadatas.variants.timeValidity.value_f": {
      "mode": "min",
      "order": "asc",
      "nested": {
        "path": "metadatas.variants.timeValidity",
        "filter": {
          "range": {
            "metadatas.variants.timeValidity.since": {
              "lte": "2018-01-21T23:59:59.999Z"
            },
            "metadatas.variants.timeValidity.until": { // forbidden !!
              "gte": "2018-01-21T23:59:59.999Z"
            }
          }
        },
        "nested": {
          "path": "metadatas.variants",
          "filter": {
            "match": {
              "metadatas.variants.value": "3Y"
            }
          },
          "nested": {
            "path": "metadatas",
            "filter": {
              "match": {
                "metadatas.name": "riskRatio"
              }
            }
          }
        }
      }
    }
  }]
}

我怎样才能正确排序?通过提升排序也可以,但对我来说是一条死胡同。


共有1个答案

段劲
2023-03-14

在查询中添加解释:true对调试和理解正在发生的事情非常有帮助。

这为您提供了一个额外的排序键,按命中显示它所采用的值。

为了能够查询两个范围,必须使用排序的filter部分中的BooleanQuery。最终正确的查询如下:

{
  "sort": [{
    "metadatas.variants.timeValidity.value_f": {
      "mode": "min",
      "order": "asc",
      "nested": {
        "path": "metadatas",
        "filter": {
          "match": {
            "metadatas.name": "riskRatio"
          }
        },
        "nested": {
          "path": "metadatas.variants",
          "filter": {
            "match": {
              "metadatas.variants.value": "3Y"
            }
          },
          "nested": {
            "path": "metadatas.variants.timeValidity",
            "filter": {
              "bool": {
                "must": [{
                  "range": {
                    "metadatas.variants.timeValidity.since": {
                      "lte": "2018-01-21T23:59:59.999Z"
                    }
                  }
                }, {
                  "range": {
                    "metadatas.variants.timeValidity.until": {
                      "gte": "2018-01-21T23:59:59.999Z"
                    }
                  }
                }]
              }
            }
          }
        }
      }
    }
  }]
}
 类似资料:
  • 问题内容: 我正在尝试在Elasticsearch中进行嵌套排序,但到目前为止没有成功。 我的数据结构: 我想根据文档中第一作者的姓氏对文档进行排序。 使用的映射: 使用SearchRequestBuilder(JAVA)进行排序: 这行得通,但没有给出想要的结果(例如,首先是“叫卖”,然后是“罗杰”)。 我错过了什么吗?有没有办法表明Elasticsearch访问数组authorList的ind

  • 我试图在Elasticsearch中进行嵌套排序,但到目前为止还没有成功。 我的数据结构: 我想根据文档中第一作者的姓氏对文档进行排序。 使用SearchRequestBuilder(JAVA)进行排序: 这是有效的,但不能给出想要的结果(例如,首先是“霍金”,然后是“罗杰”)。 我是不是漏掉了什么?是否有一种方法可以指示Elasticsearch访问数组authorlist的index=0?是否

  • 问题内容: 我有以下ES内容,基本上是网站中包含嵌套商品的产品列表。 如何按站点详细信息的数量排序? tnx! 问题答案: 从问题的示例来看,它看起来像是单个文档,但是单个json文档不可能在同一级别具有相同名称的多个字段。 因此,假设每个字段代表一个不同的顶级文档

  • 我将Elasticsearch 6与PHP结合使用。 我的文档有一个嵌套字段,如下所示: 基本上每个文档都有很多价格,但我知道每个文档只有一个价格与过滤器/查询匹配。 我用它来搜索和排序,改编自这里的教程:https://www.elastic.co/guide/en/elasticsearch/guide/current/nested-sorting.html(对PHP数组格式表示抱歉): 我得

  • 在这里,我得到了错误: “无效的术语聚合顺序路径[price>price>price.max]。术语桶只能在子聚合器路径上排序,该路径由路径中的零个或多个单桶聚合和路径末尾的最终单桶或度量聚合组成。子路径[price]指向非单桶聚合” 如果我按持续时间聚合排序,查询可以正常工作,如 那么,有什么方法可以通过嵌套字段上的嵌套聚合来排序聚合吗?

  • 我想要实现的是通过唯一对(城市、州)进行聚合。根据Elasticsearch文档,术语聚合不支持从同一文档中的多个字段收集术语。因此,我创建了一个嵌套的agg,如下所示: 作为这种聚合的结果,我得到了这样的响应: 问题是如何获得按最深doc\u计数排序的结果? 预期的有序列表应如下所示: 内华达州拉斯维加斯(5840) 杰克逊维尔,佛罗里达州(2986) 北卡罗来纳州杰克逊维尔(1962) 亚利桑