elasticsearch,nested,Sorting,elasticsearch,Nested" /> elasticsearch,nested,Sorting,elasticsearch,Nested" />

Sorting 如何在Elasticsearch中同时按父字段和嵌套字段排序?

Sorting 如何在Elasticsearch中同时按父字段和嵌套字段排序?,sorting,elasticsearch,nested,Sorting,elasticsearch,Nested,我需要同时按父字段和嵌套字段在Elasticsearch中排序。我的数据如下: [ { "id": "1", "rank": 8, "price": 12.45, "offers": [ { "id": "777",

我需要同时按父字段和嵌套字段在Elasticsearch中排序。我的数据如下:

[
    {
        "id": "1",
        "rank": 8,
        "price": 12.45,
        "offers": [
            {
                "id": "777",
                "rank": 12,
                "price": 45.75
            }
        ]
    },
    {
        "id": "2",
        "rank": 35,
        "price": 5.95,
        "offers": null
    }
]
我需要对
rank
上的结果进行排序,以便在
提供
不为
null
时,我应该使用嵌套的
提供.rank
值,否则我应该使用父级
rank
值。 我尝试了这个脚本,但没有成功:

    "sort": [
        {
            "_script": {
                "script": {
                    "source": "doc['offers'].size()==0 ? doc['rank'].value : doc['offers.rank'].value",
                    "lang": "painless"
                },
                "type": "number",
                "order": "asc"
            }
        }
    ]

它不起作用可能是因为
offers.rank
来自嵌套的
offers
对象,该对象不可访问。但我不知道如何处理它-如果我为整个脚本添加嵌套条件,那么我的父值
doc['rank']。值
将不再可访问。可以同时按父字段和嵌套字段在此处排序吗?

您正确地假设父列组将无法访问。现在,你也可以

  • 创建两个单独的排序“对象”,一个用于父级,一个用于嵌套的报价,然后使用or将结果相加
  • 迭代
    \u源代码
  • 请注意,因为我们在这里使用的是“offers”
    ArrayList
    ,所以您需要某种机制来选择排名。这取决于您--我只是访问了第一个报价的排名,您可能希望对数组列表进行排序并选择最高的一个

    如果您喜欢的话,这里有一行:

    params._source.offers instanceof ArrayList && params._source.offers.length > 0 ? params._source['offers'][0].rank : params._source.rank
    

    如果嵌套字段“提供”包含多个提议,那么在整理文档时要考虑哪些值?首先是为了简单起见。谢谢“乔”。我尝试了第二种解决方案,效果很好。虽然在条件的开头,我们需要添加一个额外的条件
    params.\u source.offers!=null
    否则请求会失败,
    ,“lang”:“无痛”,“原因”:{“type”:“null\u指针\u异常”,“原因”:null}
    。这是因为
    提供的
    可以
    为空
    。很高兴知道
    解决方案#2
    在技术上是存在的,我们可以在一个脚本中访问
    父项
    嵌套的
    字段!虽然我发现
    访问_source字段比使用doc值慢得多。
    因此我需要测试
    解决方案#2
    的性能,以了解它是否足够快,可以完成我的任务。如果性能不好,我将尝试
    解决方案#1
    。听起来不错。这完全取决于索引大小和排序文档的方式(因为排序操作发生在查询解析之后)。
    params.\u source['offers'][0]。秩
    可以以
    params.\u source.offers[0]的形式编写。秩
    ?或者后一种形式不正确,只能使用前一种形式?
    \u source
    属于
    SourceLookup
    类型,它实现了
    HashMap
    ,因此两者都是可以接受的--
    params._source.offers instanceof ArrayList && params._source.offers.length > 0 ? params._source['offers'][0].rank : params._source.rank