node.js - 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 调用,所以我希望它尽可能高效。
解决方案
该答案考虑了对 Hunter Frazier 回答说您不想使用扫描的评论。
使用查询时,您需要在操作中指定单个分区键。在您的架构中,这意味着对 userid 属性进行分区,这是一个集合。DynamoDB 中的分区键必须是顶级标量属性。由于 userid 不是标量(它是一个集合),因此您不能将此属性用作索引,因此您不能对用户所属的对话进行查询。
如果您需要执行此查询,我建议您重新访问您的架构。具体来说,我建议实施邻接列表模式,该模式在包含多对多关系的数据库中运行良好。
您可以在上面的文章中看到一些额外的注释,我在这个答案DynamoDB MM Adjacency List Design Pattern上写过
在您的情况下,您将拥有:
- 主键:ConversationID
- 排序键:用户 ID
- GSI 主键:用户 ID
然后,您可以在查询中使用 GSI 主键来返回用户参与的所有对话。
推荐阅读
- c# - C#如何在10分钟后停止定时器
- php - 我想从 PHP 中的字符串 html 中提取数据
- android - 将方向设置为 0 并且仍然在 Android 的 ImageView 中获取旋转的图像
- python - Python Selenium 中途更改 Chrome 选项
- mfc - 为什么 MFC Ado 应用程序不能在另一台计算机上运行?
- perl - 将匿名哈希插入匿名哈希以循环计数
- docker - 使用 docker compose 抑制 docker 网络以实现测试执行隔离
- javascript - 为什么我的过滤器没有按预期工作?
- javascript - 失败的道具类型:提供给“路线”的“对象”类型的无效道具“组件”,预期的“功能”
- javascript - NODEJS如何阻止在网络浏览器上发送socket.emit?