首页 > 解决方案 > DynamoDB:查询以在字符串数组中查找项目

问题描述

我可能不太了解哈希/主键在 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是一个数组,其中列出了对话参与者的用户 ID。

我需要创建一个服务来查找用户参与的所有对话。在 MongoDB(我更熟悉)中,我会做类似的事情:

Conversation.find({users: {"$in": ['foo']} }).then(.... 

我可以在 DynamoDB 中做一些等效的事情吗?这是一个经常发生的 API 调用,所以我希望它尽可能高效。

标签: node.jsamazon-dynamodbdynogels

解决方案


该答案考虑了对 Hunter Frazier 回答说您不想使用扫描的评论。

使用查询时,您需要在操作中指定单个分区键。在您的架构中,这意味着对 userid 属性进行分区,这是一个集合。DynamoDB 中的分区键必须是顶级标量属性。由于 userid 不是标量(它是一个集合),因此您不能将此属性用作索引,因此您不能对用户所属的对话进行查询。

如果您需要执行此查询,我建议您重新访问您的架构。具体来说,我建议实施邻接列表模式,该模式在包含多对多关系的数据库中运行良好。

您可以在上面的文章中看到一些额外的注释,我在这个答案DynamoDB MM Adjacency List Design Pattern上写过

在您的情况下,您将拥有:

  • 主键:ConversationID
  • 排序键:用户 ID
  • GSI 主键:用户 ID

然后,您可以在查询中使用 GSI 主键来返回用户参与的所有对话。


推荐阅读