sql - MongoDB:如何检索新构造的数据而不是集合中的原始文档?

标签 sql mongodb database

我有一个集合,其中的文档都是这种格式的:

{"user_id": ObjectId, "book_id": ObjectId}

表示用户与图书的关系,也是一对多的关系,即一个用户可以拥有多本书。

现在我得到了三个book_id,例如:

["507f191e810c19729de860ea", "507f191e810c19729de345ez", "507f191e810c19729de860efr"]

我想查询出拥有这三本书的用户,因为我要的结果不是这个集合中的文档,而是新建一个user_id的数组,看起来比较复杂,我有不知道如何进行查询,请帮助我。

注意:

我没有使用像这样的结构的原因:

{"user_id": ObjectId, "book_ids": [ObjectId, ...]}

是因为在我的系统中,书籍的增加是频繁的,而且没有数量限制,也就是说,用户可能会阅读几千本书,所以我觉得还是用传统的方式来存储比较好。

这道题不受MongoDB的限制,可以用关系数据库的思路来回答。

最佳答案

使用常规的查找,您无法取回拥有所有 book_id 的所有 user_id 字段,因为您对集合进行了规范化(扁平化)。

如果你使用聚合框架,你可以做到:

db.collection.aggregate([
    {
        $match: {
            book_id: {
                $in: ["507f191e810c19729de860ea",
                      "507f191e810c19729de345ez",
                      "507f191e810c19729de860efr" ]
            }
        }
    },
    {
        $group: {
            _id: "$user_id",
            count: { $sum: 1 }
        }
    },
    {
        $match: {
            count: 3
        }
    },
    {
        $group: {
            _id: null,
            users: { $addToSet: "$_id" }
        }
    }
]);

它所做的是仅通过管道过滤与三个 book_id 值之一匹配的文档,然后按 user_id 分组并计算该用户获得的匹配项数。如果他们得到三个,他们将传递到下一个管道操作,将它们分组到一个 user_ids 数组中。此解决方案假定每个 'user_id,book_id' 记录在原始集合中只能出现一次。

关于sql - MongoDB:如何检索新构造的数据而不是集合中的原始文档?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15491556/

相关文章:

sql - 查询中的 Azure 流分析 'TimeStamp By' 无法在作业中运行,但在测试中运行良好

node.js - 索引在Elasticsearch中创建成功,但docs.count变为0

sql - 让用户只与数据库中的一个表进行交互?

sql - Oracle RDBMS 记录是否有索引或时间戳?如何获取?

database - 获取受更新影响的行

sql - oracle 9i 中还有另一个 wm_concat 命令吗?

PHP MySQL 插入问题

node.js - NodeJS MongoDB 回调 hell

mongodb - 如何使用php计算mongo集合中的文档元素?

mysql - 1064 mysql 使用@时出错