首页 > 解决方案 > Elasticsearch查询日期排序父子关系(重复事件)

问题描述

我目前正在开发一个我们正在处理事件的应用程序。因此,在 Elasticsearch 中,我们确实有一个名为 Event 的文档。

以前,我们只有一种事件(5 月 13 日上午 9 点到 11 点发生的唯一事件),排序很简单(按 start_date 排序)

我们最近添加了一个新功能,允许我们创建重复事件,这意味着我们现在在 Elasticsearch 中有 2 个级别(父子关系)。

我们可以有一个从 5 月 12 日下午 2 点到 5 月 14 日下午 6 点的父事件,与该事件相关联,例如,我们有每天的孩子。所以我们有:5 月 12 日 2PM-6PM、5 月 13 日 2PM-6PM、5 月 14 日 2PM-6PM。

实际排序的问题在于,当我们在 5 月 12 日晚上 10 点时,我们会在列表顶部找到重复事件,然后是唯一事件。

我想进行排序,其中最近的日期具有更高的优先级。在这种情况下,唯一事件应该是列表中的第一个。

为了实现这一点,我在重复事件父节点上索引了节点子节点,以便让子节点 start_date。这个想法是从子节点中为每个重复事件获取最近的日期,并使用每个唯一事件的 start_date 对该日期进行排序。

我没有弹性搜索的丰富经验,所以我有点卡住了,我在文档中看到了很多信息(父子、嵌套对象、脚本等),但我不知道如何处理这个案子。

如果您有任何问题,我希望我已经正确解释了自己,请随时问他们,我很乐意为您提供更多信息。

标签: phpsortingelasticsearchparent-childdsl

解决方案


对于未来的谷歌人,这是我修复它的方法。

必须使用脚本并对其进行排序,这是我正在使用的请求的部分示例

GET /event/_search
{
    "query" : {
      "match_all": {}
    },
    "sort" : {
        "_script" : {
            "type" : "number",
            "script": {
              "lang": "painless",
              "params": {
                "currentDate": 1560230000
              },
              "source": """
                def isRecurrenceParent = params._source.is_recurrence_parent;
                def countChildren = params._source.children.length;
                def currentDate = params.currentDate;

                if (isRecurrenceParent === false) {
                  return params._source.timestamp;
                }

                def nearest = 0;

                def lowestDiff = currentDate;

                for (int i = 0; i < countChildren; i++) {
                  def child = params._source.children[i];

                  def diff = child.timestamp - currentDate;
                  if (diff > 0 && diff < lowestDiff) {
                    lowestDiff = diff;
                    nearest = child.timestamp;
                  }
                }

                return nearest;
"""
            },
            "order" : "asc"
        }
    }
}

推荐阅读