我们正在尝试搜索dynamodb,并需要获得组内对象的计数,如何做到这一点?
我已经尝试过了,但是当添加第二个数字时,这不起作用:
$search = array(
'TableName' => 'dev_adsite_rating',
'Select' => 'COUNT',
'KeyConditions' => array(
'ad_id' => array(
'ComparisonOperator' => 'EQ',
'AttributeValueList' => array(
array('N' => 1039722, 'N' => 1480)
)
)
)
);
$response = $client->query($search);
sql版本看起来像这样:
select ad_id, count(*)
from dev_adsite_rating
where ad_id in(1039722, 1480)
group by ad_id;
那么,我们有办法做到这一点吗?
尝试在DynamoDB上执行这样的查询比在SQL世界中稍微复杂一些。要执行这样的操作,需要考虑以下几点
- EQ ONLY Hash Key:要执行这种查询,您需要进行两个查询(即ad_id EQ 1039722/ad_id EQ 1480)
- 通过查询分页:由于dynamodb以增量方式返回结果集,因此需要对结果分页。点击这里了解更多。
- 运行"Count":您可以从响应中获取"Count"属性,并在对两个查询的结果进行分页时将其添加到运行总数中。查询API
您可以添加一个由DynamoDBStream触发的Lambda函数,以便动态地聚合您的数据,在您的示例中,将相关计数器添加+1。然后,您的搜索函数将直接检索聚合的数据。
示例:如果您有一个每周在线投票系统,您需要存储每个投票(也要检查没有用户投票两次),您可以使用以下命令实时汇总投票:
export const handler: DynamoDBStreamHandler = async (event: DynamoDBStreamEvent) => {
await Promise.all(event.Records.map(async record => {
if (record.dynamodb?.NewImage?.vote?.S && record.dynamodb?.NewImage?.week?.S) {
await addVoteToResults(record.dynamodb.NewImage.vote.S, record.dynamodb.NewImage.week.S)
}
}))
}
其中addVoteToResults类似于:
export const addVoteToResults = async (vote: string, week: string) => {
await dynamoDbClient.update({
TableName: 'table_name',
Key: { week: week },
UpdateExpression: 'add #vote :inc',
ExpressionAttributeNames: {
'#vote': vote
},
ExpressionAttributeValues: {
':inc': 1
}
}).promise();
}
之后,当投票结束时,您可以使用单个get语句检索每周的总票数。此解决方案还有助于分散写/读负载,而不是在执行搜索功能时大幅增加负载。