如何通过dynamodb实现聚合? Mongodb和couchbase都有地图缩减支持。
让我们说我们正在构建一个技术博客,用户可以发布文章。并且可以标记文章。
user
{
id : 1235,
name : "John",
...
}
article
{
id : 789,
title: "dynamodb use cases",
author : 12345 //userid
tags : ["dynamodb","aws","nosql","document database"]
}
在用户界面中,我们要显示当前用户标签和相应的计数。
如何实现以下聚合?
{
userid : 12,
tag_stats:{
"dynamodb" : 3,
"nosql" : 8
}
}
我们将通过rest api提供这些数据,并且会经常调用它。像这样的信息显示在应用主页面中。
我想知道其他更好的方法来实现同样的目标。 考虑到成本和响应时间,人们如何实现像这样的动态简单查询选择dynamodb作为主要数据存储。
答案 0 :(得分:14)
长话短说:迪纳摩不支持这一点。它不是为这个用例构建的。它旨在以低延迟进行快速数据访问。它根本不支持任何聚合功能。
您有三个主要选择:
将DynamoDB数据导出到Redshift或EMR Hive。然后,您可以对陈旧数据执行SQL查询。这种方法的好处是它只消耗一次RCU,但你会坚持使用过时的数据。
对Hive使用DynamoDB connector并直接查询DynamoDB。您可以再次编写任意SQL查询,但在这种情况下,它将直接访问DynamoDB中的数据。缺点是它会消耗你每次查询的读取容量。
使用DynamoDB streams在单独的表格中维护汇总数据。例如,您可以将表UserId作为分区键,使用带有标记和计数的嵌套映射作为属性。在原始数据的每次更新中,DynamoDB流将在主机上执行Lambda函数或某些代码以更新聚合表。这是最具成本效益的方法,但您需要为每个新查询实现其他代码。
当然,您可以在应用程序级别提取数据并在那里聚合,但我不建议这样做。除非你有一个小桌子,你需要考虑限制,只使用部分配置容量(你想消耗,比如20%的RCU用于聚合而不是100%),以及如何在多个工人之间分配你的工作
Redshift和Hive都已经知道如何做到这一点。 Redshift在执行查询时依赖于多个工作节点,而Hive则基于Map-Reduce。此外,Redshift和Hive都可以使用预定义的RCU吞吐量百分比。
答案 1 :(得分:0)
DynamoDB不支持此功能。您可以在DynamoDB上创建二级索引,但这将需要其他DynamoDB容量单位。 DynamoDB是快速的键值存储,这意味着它不具有执行复杂的聚合,排序,相关性等功能。
您需要将数据导出到数据存储。您可以通过dynamoDB-Glue-S3导出器https://aws.amazon.com/about-aws/whats-new/2018/07/aws-glue-now-supports-reading-from-amazon-dynamodb-tables/将其导出到S3。然后使用AWS Athena发出标准SQL查询来进行聚合。尝试此操作时,我发现SQL查询有时返回数据的速度很慢,尤其是在聚合复杂或数据大小很大时。
另一种方法是将Rockset与DynamoDB表连接。我发现这个描述Decore加密货币分析的用例非常类似于您的需求https://rockset.com/blog/case-study-decore-uses-rockset-for-search-and-analytics-on-dynamodb/。此案例研究显示了Rockset上的SQL查询如何快速完成并在几百毫秒内完成。
答案 2 :(得分:0)
Dynamodb是纯键/值存储,不支持现成的聚合。
如果您真的想使用DynamoDB进行聚合,请参考以下提示。
对于您的特殊情况,让我们命名名为articles
的表。
要进行汇总,我们需要一个额外的表user-stats
,其中包含userId
和tag_starts
。
articles
上启用了DynamoDB流user-stats-aggregate
,该函数已订阅文章DynamoDB流,并在articles
表的每次创建/更新/删除操作上收到OLD_NEW_IMAGES。user-stats
该用户中可能没有初始记录)通常可以使用DynamoDB流,用于进行聚合的lambda和用于保持聚合结果具有不同粒度(分钟,小时,天,年...)的额外表来完成DynamoDB中的聚合。
这带来了近乎实时的聚合,而无需在每次查询聚合数据时都立即进行。