Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sorting ElasticSearch多级父子聚合_Sorting_<img Src="//i.stack.imgur.com/RUiNP.png" Height="16" Width="18" Alt="" Class="sponsor Tag Img">elasticsearch_Aggregation - Fatal编程技术网 elasticsearch,aggregation,Sorting,elasticsearch,Aggregation" /> elasticsearch,aggregation,Sorting,elasticsearch,Aggregation" />

Sorting ElasticSearch多级父子聚合

Sorting ElasticSearch多级父子聚合,sorting,elasticsearch,aggregation,Sorting,elasticsearch,Aggregation,我有一个3级的父/子结构。让我们说: 公司->员工->可用性 由于可用性(以及员工)在这里经常更新,所以我选择对嵌套结构使用父/子结构。搜索功能工作正常(所有文档都在正确的碎片中) 现在我想对这些结果进行排序。通过公司(第一级)的元数据对它们进行排序很容易。但我还需要按第三级(可用性)进行排序 我想要按以下顺序排列的公司列表: 距离给定ASC位置的距离 评级说明 最快可用性ASC 例如: A公司距离我们5英里,评级为4级,最快的一名员工将在20小时内到达 B公司也在5英里之外,也有4级,但最

我有一个3级的父/子结构。让我们说:

公司->员工->可用性

由于可用性(以及员工)在这里经常更新,所以我选择对嵌套结构使用父/子结构。搜索功能工作正常(所有文档都在正确的碎片中)

现在我想对这些结果进行排序。通过公司(第一级)的元数据对它们进行排序很容易。但我还需要按第三级(可用性)进行排序

我想要按以下顺序排列的公司列表:

  • 距离给定ASC位置的距离
  • 评级说明
  • 最快可用性ASC
例如:

A公司距离我们5英里,评级为4级,最快的一名员工将在20小时内到达 B公司也在5英里之外,也有4级,但最快的一名员工将在5小时内到达

因此,排序结果需要是B,A

我想为每个数据添加特殊的权重,所以我开始编写聚合,稍后可以在我的自定义分数脚本中使用聚合



现在,我已经成功编写了一个查询,它实际上返回结果,但可用性聚合桶是空的。 然而,我也得到了过于结构化的结果,我想把它们展平

现在我回来了:

公司ID->员工ID->首次可用

我希望有如下聚合:

公司ID->首次上市

通过这种方式,我可以执行我的
自定义_分数
脚本来计算分数并正确排序

更简单的问题:

如何按多级(大)子级排序/聚合并可能展平结果。

您应该查看R树数据结构。

您不需要聚合来完成此操作:

以下是排序标准:

  • 距离ASC(公司位置)
  • 评级说明(公司评级值)
  • 最快的未来可用性ASC(公司、员工、可用性、开始)
  • 如果忽略#3,则可以运行一个相对简单的公司查询,如下所示:

    GET /companies/company/_search
    {
     "query": { "match_all" : {} },
     "sort": {
        "_script": {
            "params": {
                "lat": 51.5186,
                "lon": -0.1347
            },
            "lang": "groovy",
            "type": "number",
            "order": "asc",
            "script": "doc['location'].distanceInMiles(lat,lon)"
        },
        "rating_value": { "order": "desc" }
      }
    }
    
    #3是一个棘手的问题,因为您需要找到最接近请求时间的每个公司的可用性(公司>员工>可用性),并将该持续时间用作第三个排序标准

    我们将在孙子级别使用
    函数\u score
    查询来获取请求时间和hit
    \u score
    中每个可用性之间的时间差。(然后我们将使用
    \u评分
    作为第三个排序标准)

    为了联系孙子辈,我们需要在
    has\u child
    查询中使用
    has\u child
    查询

    对于每一家公司,我们都需要最快可用的员工(当然还有他们最接近的可用性)。Elasticsearch 2.0将为我们提供一个
    “分数模式”:“min”
    用于此类情况,但目前,由于我们仅限于
    “分数模式”:“max”
    我们将使孙子
    \u分数
    为时差的倒数

              "function_score": {
                "filter": { 
                  "range": { 
                    "start": {
                      "gt": "2014-12-22T10:34:18+01:00"
                    } 
                  }
                },
                "functions": [
                  {
                    "script_score": {
                      "lang": "groovy",
                      "params": {
                          "requested": "2014-12-22T10:34:18+01:00",
                          "millisPerHour": 3600000
                       },
                      "script": "1 / ((doc['availability.start'].value - new DateTime(requested).getMillis()) / millisPerHour)"
                    }
                  }
                ]
              }
    
    因此,现在每个孙子女(可用性)的
    \u分数将是
    1/可用时数
    (这样我们可以使用每个员工可用时的最大互惠时间,以及每个公司可用员工的最大互惠时间)

    总而言之,我们继续查询公司,但使用公司>员工>可用性生成
    \u分数
    ,用作\3排序标准:

    GET /companies/company/_search
    {
     "query": { 
        "has_child" : {
            "type" : "employee",
            "score_mode" : "max",
            "query": {
              "has_child" : {
                "type" : "availability",
                "score_mode" : "max",
                "query": {
                  "function_score": {
                    "filter": { 
                      "range": { 
                        "start": {
                          "gt": "2014-12-22T10:34:18+01:00"
                        } 
                      }
                    },
                    "functions": [
                      {
                        "script_score": {
                          "lang": "groovy",
                          "params": {
                              "requested": "2014-12-22T10:34:18+01:00",
                              "millisPerHour": 3600000
                           },
                          "script": "1/((doc['availability.start'].value - new DateTime(requested).getMillis()) / millisPerHour)"
                        }
                      }
                    ]
                  }
                }
              }
            }
        }
     },
     "sort": {
      "_script": {
        "params": {
            "lat": 51.5186,
            "lon": -0.1347
        },
        "lang": "groovy",
        "type": "number",
        "order": "asc",
        "script": "doc['location'].distanceInMiles(lat,lon)"
      },
      "rating_value": { "order": "desc" },
      "_score": { "order": "asc" }
     }
    }
    

    能否将映射和一些示例文档(带子体)添加到要点中?很难想象如何发明伪造的文档来对您的系统进行充分的测试。为了便于理解,我把它剥去了一点。完整的堆栈中有很多的更多数据:)谢谢!我也有同样的问题。虽然性能可能不太好,但我只是请求所有具有默认DocCount排序的结果。然后,我自己做了递归展平、排序和限制,这并不理想。我已经执行了您的要点,但在搜索时,我得到错误500
    Query Failed[未能执行主查询];嵌套:NullPointerException。你能在你当地的环境中执行你的要点并确保它是正确的吗?谢谢为什么不为你的结果建立一个方程式呢。你的数据不模糊!您聚合了每个查询。聚合是输入操作,而不是查询或输出。一个问题“您如何检查此结果是否正确(右)?”您可以使用一个而不是一个脚本从时间到可用时间生成
    \u分数
    。默认情况下,Elasticsearch禁用了动态脚本。更好的方法是使用索引脚本。看这里:皮特:你能让它工作吗?我知道这是一个老问题,但是有很多人对你的解决方案感兴趣。Peter Dixon Moses:最终我放弃了,写了两个查询——首先按公司/员工搜索,然后通过可用性搜索前100家公司,然后合并。为什么?仅在ES中构建它花费了太多的时间/精力。花在搜索上的时间是可以接受的。