我有一个集合,其中的文档都是这种格式:
{"user_id": ObjectId, "book_id": ObjectId}
它代表用户和书籍之间的关系,也是一对多的关系,这意味着用户可以拥有多本书。
现在我有三个book_id
,例如:
["507f191e810c19729de860ea", "507f191e810c19729de345ez", "507f191e810c19729de860efr"]
我想查询拥有这三本书的用户,因为我想要的结果不是这个集合中的文档,而是一个新构造的user_id
数组,看起来很复杂,我不知道如何进行查询,请帮帮我。
注意:
我没有使用如下结构的原因:
{"user_id": ObjectId, "book_ids": [ObjectId, ...]}
是因为在我的系统中,书籍频繁增加并且数量没有限制,换句话说,用户可能会阅读数千本书,所以我认为最好使用传统方式来存储它。
这个问题不受MongoDB的限制,你可以在关系数据库的思想中回答它。
答案 0 :(得分:2)
使用常规find
,您无法取回拥有所有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_id数组。此解决方案假定每个'user_id,book_id'记录只能在原始集合中出现一次。