我有一个存储在mongodb中的文件:
shop: {
_id: '...'
title: 'my shop'
users: [
{
_id: '...',
name: 'user1',
username: '...'
},
{
_id: '...',
name: 'user2',
username: '...'
}
]
}
Run Code Online (Sandbox Code Playgroud)
我使用此查询通过其id获取子文档用户:
Shop.findOne({'users._id': userId}, {'users.$': 1}, function (err, user) {
console.log(user);
});
Run Code Online (Sandbox Code Playgroud)
输出:
{ _id: ...,
users:
[{
name: 'user1',
username: '...',
_id: ...
}]
}
Run Code Online (Sandbox Code Playgroud)
如何过滤结果以仅返回用户名.我现在这样做的方式:
Shop.findOne({'users._id': userId}, {'users.$': 1}, function (err, shop) {
shop = shop.toObject()
user = shop.users[0]
filtered = {
name: user.name
}
callback(filtered);
});
Run Code Online (Sandbox Code Playgroud)
但是有更好的方法在查询中完成所有操作吗?
这个问题差不多有两年了,但我注意到人们仍然在寻找解决这个问题的方法.fernandopasik的回答对我很有帮助,但缺少关于如何使用建议的聚合操作的代码示例.这就是我发布更详细答案的原因.我使用的文件是:
{
_id: '...'
title: 'my shop'
users: [
{
_id: 'user1Id',
name: 'user1',
username: '...'
},
{
_id: 'user2Id',
name: 'user2',
username: '...'
}
]
}
Run Code Online (Sandbox Code Playgroud)
我提出的解决方案(在阅读有关聚合的mongodb文档后)是:
Shop.aggregate([
{$unwind: '$users'},
{$match: {'users._id': 2}},
{$project: {_id: 0, 'name': '$users.name'}}
]);
Run Code Online (Sandbox Code Playgroud)
要了解聚合如何工作,最好一次尝试一个操作并阅读此操作的mongodb文档.
Shop.aggregate([{$unwind: '$users'}])$ unwind解构用户数组(不要忘记在数组名称中包含$),所以最终得到:
{
_id: '...',
title: 'my shop',
users: {
_id: 'user1Id',
name: 'user1',
username: '...'
}
}
{
_id: '...',
title: 'my shop',
users: {
_id: 'user2Id',
name: 'user2',
username: '...'
}
}
Run Code Online (Sandbox Code Playgroud)
2. {$match: {'users._id': 'user2Id'}}在聚合管道上使用(本例中的两个文档)将返回users._id为'user2Id'的整个文档:
{
_id: '...',
title: 'my shop',
users: {
_id: 'user2Id',
name: 'user2',
username: '...'
}
}
Run Code Online (Sandbox Code Playgroud)
3.仅返回名称:'user2'可以使用{$project: {_id: 0, 'name': '$users.name'}}:
{name: 'user2'}
Run Code Online (Sandbox Code Playgroud)
聚合管道起初并不容易掌握.我建议阅读mongodb聚合文档并一次尝试一个聚合操作.有时很难发现整个聚合管道中的错误.大多数情况下,当管道中某处出现错误时,您只是从管道中获取结果文档.
| 归档时间: |
|
| 查看次数: |
2972 次 |
| 最近记录: |