例如,我有一个users集合。每个用户文档都有包含其帖子的posts数组。我想像这样查询这个集合:
从索引Nstart开始,以用户名数组中的每个用户的Nend结尾,获取两个帖子:['user1', 'user2'],并返回一个合并的帖子数组,按post.postedOn int的升序排序。
如果这是集合:
{
username: "user1",
posts: [
{ id: 1, text: "123" ... },
{ id: 2, text: "456" ... },
{ id: 3, text: "789" ... },
...
]
},
{
username: "user2",
posts: [
{ id: 1, text: "abc" ... },
{ id: 2, text: "def" ... },
{ id: 3, text: "ghi" ... },
...
]
}
...我想得到这个:
{
posts: {
{ id: 1, text: "123" ... },
{ id: 2, text: "456" ... },
{ id: 1, text: "abc" ... },
{ id: 2, text: "def" ... },
}
}我已经多次使用aggregate了。这是我的一个问题:
db.getCollection("users").aggregate([{ $match: { username: { $in: ["admin", "admin2"] } } }, { $project: { posts: 1 } }])我得到两个用户对象,每个对象都包含所有的帖子,而不是一个以后可以操作的posts数组。
我想要达到的最后结果是:
输入
['user1', 'user2']48结果
选定用户的帖子数组。总数为8(每个用户的id 4-8 )。
发布于 2019-10-14 05:58:07
这需要使用聚合操作符$slice和$push分别在数组中选择和添加所需的post元素(按索引)。
例如,posts集合有三个文档(我在这里省略了_id字段):
{
"username" : "user2",
"posts" : [
{
"id" : 1,
"text" : "123"
},
{
"id" : 2,
"text" : "456"
},
{
"id" : 3,
"text" : "789"
},
{
"id" : 4,
"text" : "000"
}
]
}
{
"username" : "user1",
"posts" : [
{
"id" : 1,
"text" : "abc"
},
{
"id" : 2,
"text" : "def"
},
{
"id" : 3,
"text" : "ghi"
},
{
"id" : 4,
"text" : "zzz"
}
]
}
{
"username" : "user99",
"posts" : [ ]
}芒果壳中的:
> var users = [ "user1", "user2" ]
> var startIx = 1, noOfElements = 2
> db.posts.aggregate([
{ $project: { _id: 0, username: 1, posts: 1, usersMatch: { $in: [ "$username", users ] } } },
{ $match: { usersMatch: true } },
{ $addFields: { posts: { $slice: [ "$posts", startIx, noOfElements ] } } },
{ $group: { _id: null, postsOfSelectedUsers: { $push: "$posts"} } },
{ $project: { _id: 0, selectedUsers: users, postsOfSelectedUsers: 1 } }
])输出:
{
"postsOfSelectedUsers" : [
[
{
"id" : 2,
"text" : "456"
},
{
"id" : 3,
"text" : "789"
}
],
[
{
"id" : 2,
"text" : "def"
},
{
"id" : 3,
"text" : "ghi"
}
]
],
"selectedUsers" : [
"user1",
"user2"
]
}注意事项:这是一个解决方案,但可以改进或重新设计(我认为)。
https://stackoverflow.com/questions/58364312
复制相似问题