MongoDB嵌套对象的聚合过滤
MongoDB aggregation filtering of a nested object
我需要过滤一组嵌套对象,并且只过滤 return 那些 active.email
设置为 true 的对象。
到目前为止我有一个聚合:
db.subscriptions.aggregate([
{
$match: { user: ObjectId('5f9a4f3070bd08b002498d43') },
},
{
$project: {
'subscriptions.user': 1,
'subscriptions.active.email': 1,
},
})
哪个return是单个用户的订阅文档:
{
"_id" : ObjectId("5f9a4f3170bd08b002498d44"),
"subscriptions" : [
{
"active" : {
"email" : true
},
"user" : ObjectId("5f9a4e5071713dc6120df47f")
},
{
"active" : {
"email" : true
},
"user" : ObjectId("5f9b7f2dc16811a281113ba1")
},
{
"active" : {
"email" : false
},
"user" : ObjectId("5f9b7e8ac16811a281113b9f")
}
]
}
如果我尝试对其使用过滤器:
db.subscriptions.aggregate([
{
$match: { user: ObjectId('5f9a4f3070bd08b002498d43') },
},
{
$project: {
'subscriptions.user': 1,
'subscriptions.active.email': 1,
},
},
{
$filter: {
input: '$subscriptions',
as: 'subs',
cond: { '$$subs.active.email': true },
},
},
它给我这个错误:"Unrecognized pipeline stage name: '$filter'",
这是我想要的输出:
"subscriptions" : [
{
"active" : {
"email" : true
},
"user" : ObjectId("5f9a4e5071713dc6120df47f")
},
{
"active" : {
"email" : true
},
"user" : ObjectId("5f9b7f2dc16811a281113ba1")
},
]
在此使用过滤器的正确方法是什么?我最初尝试在查询中使用 $elemMatch
,但由于它是嵌套的,因此无法完成。另外,如果有其他方法,我洗耳恭听。
您需要在 $match 主 _id 后展开“订阅”数组,之后您需要再次 $match 活动邮件。使用 $project 创建更好的输出。确保您只查询一个主要的 _id,否则这将导致潜在不同用户的多个项目变得混乱。
db.subscriptions.aggregate([
{
$match: { _id: ObjectId('5f9a4f3170bd08b002498d44') },
},
{
$unwind: {
path: '$subscriptions',
},
},
{
$match: {
'subscriptions.active.email': true,
},
},
{
$project: {
activeUserId: '$subscriptions.user',
_id: 0,
},
},
])
我需要过滤一组嵌套对象,并且只过滤 return 那些 active.email
设置为 true 的对象。
到目前为止我有一个聚合:
db.subscriptions.aggregate([
{
$match: { user: ObjectId('5f9a4f3070bd08b002498d43') },
},
{
$project: {
'subscriptions.user': 1,
'subscriptions.active.email': 1,
},
})
哪个return是单个用户的订阅文档:
{
"_id" : ObjectId("5f9a4f3170bd08b002498d44"),
"subscriptions" : [
{
"active" : {
"email" : true
},
"user" : ObjectId("5f9a4e5071713dc6120df47f")
},
{
"active" : {
"email" : true
},
"user" : ObjectId("5f9b7f2dc16811a281113ba1")
},
{
"active" : {
"email" : false
},
"user" : ObjectId("5f9b7e8ac16811a281113b9f")
}
]
}
如果我尝试对其使用过滤器:
db.subscriptions.aggregate([
{
$match: { user: ObjectId('5f9a4f3070bd08b002498d43') },
},
{
$project: {
'subscriptions.user': 1,
'subscriptions.active.email': 1,
},
},
{
$filter: {
input: '$subscriptions',
as: 'subs',
cond: { '$$subs.active.email': true },
},
},
它给我这个错误:"Unrecognized pipeline stage name: '$filter'",
这是我想要的输出:
"subscriptions" : [
{
"active" : {
"email" : true
},
"user" : ObjectId("5f9a4e5071713dc6120df47f")
},
{
"active" : {
"email" : true
},
"user" : ObjectId("5f9b7f2dc16811a281113ba1")
},
]
在此使用过滤器的正确方法是什么?我最初尝试在查询中使用 $elemMatch
,但由于它是嵌套的,因此无法完成。另外,如果有其他方法,我洗耳恭听。
您需要在 $match 主 _id 后展开“订阅”数组,之后您需要再次 $match 活动邮件。使用 $project 创建更好的输出。确保您只查询一个主要的 _id,否则这将导致潜在不同用户的多个项目变得混乱。
db.subscriptions.aggregate([
{
$match: { _id: ObjectId('5f9a4f3170bd08b002498d44') },
},
{
$unwind: {
path: '$subscriptions',
},
},
{
$match: {
'subscriptions.active.email': true,
},
},
{
$project: {
activeUserId: '$subscriptions.user',
_id: 0,
},
},
])