我可能不太理解DynamoDB中的散列/主键是如何工作的,但我正在尝试为消息传递服务创建一个模型(使用无服务器+ Dynogels/NodeJS)。
该模型如下所示:
const ConversationORM = dynogels.define('Conversation', {
hashKey: 'id',
timestamps: true,
tableName: config.CONVERSATION_TABLE,
schema: {
id: Joi.string(),
users: Joi.array(), // e.g. ['foo', 'bar', 'moo']
messages: Joi.array()
}
})如您所见,users是一个数组,它列出了会话参与者的userIds。
我需要创建一个服务,找到一个用户正在参与的所有对话。在MongoDB (我更熟悉它)中,我会这样做:
Conversation.find({users: {"$in": ['foo']} }).then(.... 在DynamoDB中有没有类似的功能?这是一个经常发生的API调用,所以我希望让它尽可能高效。
发布于 2018-05-21 16:37:12
这个答案考虑到了Hunter Frazier的回答,说你不想使用扫描。
当使用Query时,您需要在操作中指定单个分区键。在您的模式中,这意味着对userid属性进行分区,这是一个集合。DynamoDB中的分区键必须是顶级标量属性。由于userid不是标量(它是一个集合),因此不能将该属性用作索引,因此不能查询用户所参与的会话。
如果您需要执行此查询,我建议重新访问您的模式。具体地说,我建议实现Adjacency list pattern,它在包含多对多关系的数据库中工作得很好。
你可以在上面的文章中看到一些额外的注释,我已经在这个答案DynamoDB M-M Adjacency List Design Pattern上写过了
在您的情况下,您将拥有:
然后,可以在查询中使用GSI主键返回用户所参与的所有会话。
发布于 2018-05-21 12:27:16
我不熟悉Dynogels或Serverless,但如果它使用常规API,这可能会起作用:
var params = {
ExpressionAttributeNames: {
"U": "users"
},
ExpressionAttributeValues: {
":a": {
S: "John Doe"
}
},
FilterExpression: "Author = :a",
ProjectionExpression: "#U",
TableName: "Conversations"
};
dynamodb.scan(params, function (err, data) {
if (err) console.log(err, err.stack);
else console.log(data);
});https://stackoverflow.com/questions/50441870
复制相似问题