如何聚合数组中匹配的值然后排序
How to aggregate with value matched in an array then sort
我有这些合集:
lists
{_id: 1, item: "a", owner: 1}
users
{_id: 1, subs: [{_id: 1, active: "Y"},{_id: 2, active: "N"}]}
subs
{_id: 1, text: "A"}
{_id: 2, text: "B"}
我想要一个包含用户信息和活动订阅者信息的列表结果。
{_id: 1, item: "a", owner: {_id: 1, subs: [{_id: {_id: 1, text: "A"}, active: "Y"}]}}
我还想根据“文本”字段对其进行排序。
我尝试聚合但失败了,
db.getCollection("lists").aggregate(
[
{
"$lookup" : {
"from" : "users",
"localField" : "owner",
"foreignField" : "_id",
"as" : "owner"
}
},
{
"$match" : {
"owner.0.subs" : {
"$elemMatch" : {
"active" : "Y"
}
}
}
}
],
{
"allowDiskUse" : false
}
);
我也在使用 Mongoose,但使用 populate 失败了。
有什么办法可以得到我的结果吗?
在这里,我更新了我的聚合管道,
[
{
$lookup: {
from: "users",
as: "owner",
let: { owner: "$owner" },
pipeline: [
{ $match: { $expr: { $eq: ["$$owner", "$_id"] } } },
{ $unwind: { path:"$sub", preserveNullAndEmptyArrays: false} },
{ $match: { "subs.active": "Y" } },
{
$lookup: {
from: "plans",
localField: "subs._id",
foreignField: "_id",
as: "subs.plans"
}
},
{ $unwind: { path:"$subs.plans", preserveNullAndEmptyArrays: false} },
]
}
},
{ $unwind: { path: "$owner", preserveNullAndEmptyArrays: true} },
{ '$sort': { item: 1 } },
{ '$skip': 0 },
{ '$limit': 20 } ]
您可以使用管道查找和嵌套查找,
内部查找管道是:
$match
您在用户中的所有者 ID collection
$unwind
解构 subs
数组,因为我们需要使用 subs
collection 进行查找
$match
订阅者是否活跃
$lookup
有替补 collection
$unwind
解构我们从 subs collection 加入的 subs._id
$group
重构subs
数组
$unwind
解构owner
数组
$sort
通过 item
和分页通过 $skip
和 $limit
db.getCollection("lists").aggregate([
{
$lookup: {
from: "users",
as: "owner",
let: { owner: "$owner" },
pipeline: [
{ $match: { $expr: { $eq: ["$$owner", "$_id"] } } },
{ $unwind: "$subs" },
{ $match: { "subs.active": "Y" } },
{
$lookup: {
from: "subs",
localField: "subs._id",
foreignField: "_id",
as: "subs._id"
}
},
{ $unwind: "$subs._id" },
{
$group: {
_id: "$_id",
subs: {
$push: {
_id: "$subs._id._id",
text: "$subs._id.text",
active: "$subs.active"
}
}
}
}
]
}
},
{ $unwind: "$owner" },
{ $sort: { item: 1 } },
{ $skip: 0 },
{ $limit: 20 }
], { allowDiskUse: false })
你的第二次编辑:在第一个 $unwind 中的第一次查找中有错误的键名 sub
,更正此,
{ $unwind: { path:"$sub", preserveNullAndEmptyArrays: false} }
到
{ $unwind: { path:"$subs", preserveNullAndEmptyArrays: false} }
我有这些合集:
lists
{_id: 1, item: "a", owner: 1}
users
{_id: 1, subs: [{_id: 1, active: "Y"},{_id: 2, active: "N"}]}
subs
{_id: 1, text: "A"}
{_id: 2, text: "B"}
我想要一个包含用户信息和活动订阅者信息的列表结果。
{_id: 1, item: "a", owner: {_id: 1, subs: [{_id: {_id: 1, text: "A"}, active: "Y"}]}}
我还想根据“文本”字段对其进行排序。
我尝试聚合但失败了,
db.getCollection("lists").aggregate(
[
{
"$lookup" : {
"from" : "users",
"localField" : "owner",
"foreignField" : "_id",
"as" : "owner"
}
},
{
"$match" : {
"owner.0.subs" : {
"$elemMatch" : {
"active" : "Y"
}
}
}
}
],
{
"allowDiskUse" : false
}
);
我也在使用 Mongoose,但使用 populate 失败了。 有什么办法可以得到我的结果吗?
在这里,我更新了我的聚合管道,
[
{
$lookup: {
from: "users",
as: "owner",
let: { owner: "$owner" },
pipeline: [
{ $match: { $expr: { $eq: ["$$owner", "$_id"] } } },
{ $unwind: { path:"$sub", preserveNullAndEmptyArrays: false} },
{ $match: { "subs.active": "Y" } },
{
$lookup: {
from: "plans",
localField: "subs._id",
foreignField: "_id",
as: "subs.plans"
}
},
{ $unwind: { path:"$subs.plans", preserveNullAndEmptyArrays: false} },
]
}
},
{ $unwind: { path: "$owner", preserveNullAndEmptyArrays: true} },
{ '$sort': { item: 1 } },
{ '$skip': 0 },
{ '$limit': 20 } ]
您可以使用管道查找和嵌套查找,
内部查找管道是:
$match
您在用户中的所有者 ID collection$unwind
解构subs
数组,因为我们需要使用subs
collection 进行查找
$match
订阅者是否活跃$lookup
有替补 collection$unwind
解构我们从 subs collection 加入的 $group
重构subs
数组$unwind
解构owner
数组$sort
通过item
和分页通过$skip
和$limit
subs._id
db.getCollection("lists").aggregate([
{
$lookup: {
from: "users",
as: "owner",
let: { owner: "$owner" },
pipeline: [
{ $match: { $expr: { $eq: ["$$owner", "$_id"] } } },
{ $unwind: "$subs" },
{ $match: { "subs.active": "Y" } },
{
$lookup: {
from: "subs",
localField: "subs._id",
foreignField: "_id",
as: "subs._id"
}
},
{ $unwind: "$subs._id" },
{
$group: {
_id: "$_id",
subs: {
$push: {
_id: "$subs._id._id",
text: "$subs._id.text",
active: "$subs.active"
}
}
}
}
]
}
},
{ $unwind: "$owner" },
{ $sort: { item: 1 } },
{ $skip: 0 },
{ $limit: 20 }
], { allowDiskUse: false })
你的第二次编辑:在第一个 $unwind 中的第一次查找中有错误的键名 sub
,更正此,
{ $unwind: { path:"$sub", preserveNullAndEmptyArrays: false} }
到
{ $unwind: { path:"$subs", preserveNullAndEmptyArrays: false} }