我有两个收藏集User
和Post
。
用户
发布
从rdb的角度来看,User:Post关系为1:N。
每个user
可以写多个post
。
例如,当前这样插入文档。
用户
> db.user.find()
{ "_id" : ObjectId("5d15e41a1b48d9417ebc28d2"), "user_id" : NumberLong(1), "region" : "US", "is_join" : true }
{ "_id" : ObjectId("5d15e41a1b48d9417ebc28d5"), "user_id" : NumberLong(2), "region" : "KR", "is_join" : true }
{ "_id" : ObjectId("5d15e41a1b48d9417ebc28d8"), "user_id" : NumberLong(3), "region" : "US", "is_join" : true }
{ "_id" : ObjectId("5d15e41a1b48d9417ebc28da"), "user_id" : NumberLong(4), "region" : "KR", "is_join" : false }
{ "_id" : ObjectId("5d15e41a1b48d9417ebc28dc"), "user_id" : NumberLong(5), "region" : "US", "is_join" : true }
发布
> db.post.find()
{ "_id" : ObjectId("5d15e41a1b48d9417ebc28d3"), "post_id" : NumberLong(1), "user_id" : NumberLong(1), "body" : "first", "is_block" : false }
{ "_id" : ObjectId("5d15e41a1b48d9417ebc28d4"), "post_id" : NumberLong(4), "user_id" : NumberLong(1), "body" : "fourth", "is_block" : false }
{ "_id" : ObjectId("5d15e41a1b48d9417ebc28d6"), "post_id" : NumberLong(2), "user_id" : NumberLong(2), "body" : "second", "is_block" : false }
{ "_id" : ObjectId("5d15e41a1b48d9417ebc28d7"), "post_id" : NumberLong(3), "user_id" : NumberLong(2), "body" : "third", "is_block" : false }
{ "_id" : ObjectId("5d15e41a1b48d9417ebc28d9"), "post_id" : NumberLong(5), "user_id" : NumberLong(3), "body" : "fifth", "is_block" : true }
{ "_id" : ObjectId("5d15e41a1b48d9417ebc28db"), "post_id" : NumberLong(6), "user_id" : NumberLong(4), "body" : "sixth", "is_block" : false }
{ "_id" : ObjectId("5d15e41a1b48d9417ebc28dd"), "post_id" : NumberLong(7), "user_id" : NumberLong(5), "body" : "seven", "is_block" : true }
{ "_id" : ObjectId("5d15e41a1b48d9417ebc28de"), "post_id" : NumberLong(8), "user_id" : NumberLong(5), "body" : "eight", "is_block" : false }
要通过聚集进行联接,还需要满足更多条件。
region='US'
,is_join=true
is_block=false
post_id
排序preserveNullAndEmptyArrays
执行,但是我认为这会导致性能问题。所需结果
{
"posts" : [
{
"post_id" : NumberLong(1),
"body" : "first",
"is_block" : false
},
{
"post_id" : NumberLong(2),
"body" : "second",
"is_block" : false
},
{
"post_id" : NumberLong(3),
"body" : "third",
"is_block" : false
},
{
"post_id" : NumberLong(4),
"body" : "fourth",
"is_block" : false
},
{
"post_id" : NumberLong(8),
"body" : "eight",
"is_block" : false
}
]
}
post_id = 5
被is_block=true
排除
post_id = 6
被is_join=false
排除
post_id = 7
被is_block=true
排除
整个结果按post_id
排序。
我是mongodb的新手,所以,也许我以关系数据库的形式想得太多。
我不知道它可以在NoSQL上执行。
有什么办法吗?
任何建议,非常感谢。
谢谢。
答案 0 :(得分:1)
您可以使用查找管道运算符获得这种结果。
const region = 'US';
const is_join = true;
const is_block = false;
const query = [
{
$match: {
region: region,
is_join: is_join
}
},
{
$lookup: {
let: { user_id: "$user_id" },
from: 'posts',
pipeline: [
{
$match: {
$expr: {
$and: [
{ $eq: ["$$user_id", "$user_id"], },
{ $eq: ["$is_block", is_block] }
]
}
}
},
{
$sort: {
post_id: 1
}
}
],
as: "posts"
}
},
{
$unwind: "$posts"
},
{
$group:{
_id: "mygroup",
posts: {
$push: {
post_id: "$posts.post_id",
body: "$posts.body",
is_block: "$posts.is_block",
}
}
}
},
{
$project:{
_id: false
}
}
]
db.users.aggregate(query)
输出
{
"posts" : [
{
"post_id" : 1,
"body" : "first",
"is_block" : false
},
{
"post_id" : 4,
"body" : "fourth",
"is_block" : false
},
{
"post_id" : 8,
"body" : "eight",
"is_block" : false
}
]
}
答案 1 :(得分:0)
尝试一下-
要加入两个集合,可以将聚合用作-
User.aggregate([{
'$match': { 'region':'US', 'is_join': true } // match from users collection
}, {
$lookup: { // it will aggregate the result from both collection
from: 'posts',
localField: '_id',
foreignField: 'user_id',
as: 'posts'
}
},
{"$unwind":"$posts"},
{$match : { "posts.is_block" : false } }, // check inside post collection
{$sort : { "posts.post_id" : 1}}, // sort the data
], (err, users) => {
if (err) return callback(err, null);
console.log('users :', users);
});