获取最新的文档版本并汇总结果

时间:2016-09-22 21:51:00

标签: elasticsearch nosql

我的索引包含很多文档,每个文档都有几个版本,例如:

{"doc_id": 13,
"version": 1,
"text": "bar"}

{"doc_id": 13,
"version": 2,
"text": "bar"}

{"doc_id": 13,
"version": 3,
"text": "bar"}

{"doc_id": 14,
"version": 1,
"text": "foo"}

{"doc_id": 14,
"version": 2,
"text": "bar"}

我想获取每个文档的最新版本,并使用terms聚合聚合它们(最新版本)。
我已尝试使用top hits检索上一版本:

{"size" :0,
"aggs" : {
    "doc_id_groups" : {
        "terms" : {
            "field" : "doc_id",
            "size" : "0"
        },
        "aggs" : {
            "docs" : {
                "top_hits" : {
                    "size" : 1,
                    "sort" : {
                        "version" : {
                            "order" : "desc"
                        }
                    }
                }
            }
        }
    }
}
}

但我无法进行汇总,因为top hits不支持子汇总。
我想检索id然后聚合它们对于客户来说将是非常繁重的操作 也许脚本可以帮助?

更新:有一件事我忘了提及:在汇总文档之前按时间范围进行过滤,因此我们不知道哪个版本是索引时的最新版本,仅在搜索时

2 个答案:

答案 0 :(得分:2)

根据提供的样本和chat中的其他详细信息,我认为您无法使用聚合获得所需的结果。但我可以提出替代解决方案:

  1. 添加属性" 当前 "类型布尔 对于所有最新版本的文档,将设置为true。如果 插入新版本 - " 当前 "将设置为 false 在旧版本中,在较新版本中设置为true。
  2. 添加属性" 时间点 "它将包含多个值。在所有的一天结束时(任何其他时期都可以使用) 当前记录添加当前时间戳(或任何其他ID) 期间,例如" 09.30.2016"或" Jan")到" 时间点 " 阵列。
  3. <强>赞成

    • 您可以在某个时间点轻松检索当前记录,只需检查时间点是否在&#34; 时间点 &#34;阵列

    • 您可以通过一次查询从所有文档中检索所有可用时间点。

    • 您可以按时间点进行汇总,例如计算每个时间点的所有记录。

    • 无需维护多个索引,重复记录等,算法非常简单。

    <强>缺点

    • 无法在任意时间点获取当前版本,只能执行计算时的版本。

    • &#34;时间点的总体大小&#34;如果您经常运行计算并且您有数百万条记录,则数组可能会显着增加。

    <强>变通方法

    • 对于更精细的统计数据,每小时运行一次计算。但是,每天(或一个月或一年)从&#34; 时间点 &#34;中删除一些时间点。较长时间的数组。最后,你将拥有一组时间点,这些时间点对应于每年(如果超过一年前),每个月(如果超过一个月前),每天(如果是超过一天前),以及最近一段时间的每小时。当然,可以根据需要改进时间点的删除算法。

    • 如果您主要使用最新版本的记录 - 将它们存储在单独的索引中,请将旧版本存储在另一个版本中。在这种情况下,你甚至不需要&#34;当前&#34; property,只需遍历当前索引中的所有记录并添加时间戳。

    如果需要,我可以为您提供上述步骤所需的所有查询。

答案 1 :(得分:0)

你应该考虑解决这个客户端问题。我可以想到两种方法来接近它。

  1. 使用滚动API查看所有文档并找到每个文档的最新版本。然后是客户端,由text汇总。
  2. doc_id上使用弹性搜索字词聚合,并在version上使用max aggregation的子聚合。这将为您提供每个文档ID的最新版本。然后创建一个布尔OR术语过滤器,该过滤器使用第一部分中的doc_id和版本。然后,此过滤器应在text上具有术语聚合。
  3. 无论哪种方式,您都需要做一些客户端工作。我不相信脚本会有所帮助。如果您已经知道每个文档的最新版本号,那么这就容易多了。