给出以下模式:
const usersSchema = Schema({
image : {type: String},
firstName: {type: String},
lastName : {type: String},
club : {type: String, ref: 'clubs'}
}, {strict: true, useNestedStrict: true});
const Users = mongoose.model('Users', usersSchema);
const clubsSchema = Schema({
image: {type: String},
name : {type: String},
}, {strict: true, useNestedStrict: true});
const clubs = mongoose.model('clubs', clubsSchema);
因此,您有一个用户列表,每个用户都属于一个俱乐部,该俱乐部另存为子文档引用。
现在,我有一个汇总查询来进行搜索。 (注意:我的实际查询和模式要复杂得多,有许多子文档,在本文中我已经简化了它)
let activePage = 0;
let resultsPerPage = 10;
let results = await Users.aggregate([
{$sort: {firstName: 1, lastName: 1, club.name: 1}},
{$lookup: {from: 'clubs', localField: 'club', foreignField: '_id', as: 'club'}},
{$unwind: "$club"},
{$project: {"_id": true, "image": true, "firstName": true, "lastName": true, "club._id": true, "club.name": true, "club.image": true}},
{$match: {firstName: "Dave"}},
{$group: {
_id : '$_id',
image : {$first: "$image"},
firstName: {$first: "$firstName"},
lastName : {$first: "$lastName"},
club : {
$first: {
_id : "$club._id",
name : "$club.name",
image: "$club.image"
}
}
}
}},
{$facet: {count: [{$count: "count"}], records: [{$skip: activePage}, {$limit: activePage * resultsPerPage}]}}
]);
运行查询时,我得到以下(样本)数据:
results.count[0].count // 4
results.records:
_id | image | firstName | lastName | club._id | club.name | club.image
111 | <data> | Dave | Burns | c123 | admins | <data>
222 | <data> | Dave | Simpson | c123 | admins | <data>
333 | <data> | Dave | Sanchez | c123 | admins | <data>
444 | <data> | Dave | Smith | c456 | losers | <data>
到目前为止,一切都按设计进行。
但是我不喜欢这样的事实,俱乐部数据会为每条记录重复...管理俱乐部ID,名称和图像重复了3次。嘘!
我想做的就是拥有它,因此我将club._id保留在记录数据中,然后在结果对象中拥有另一个属性,其中将包含匹配的俱乐部。
我要结束这个:
results.count[0].count // 4
results.records:
_id | image | firstName | lastName | club._id
111 | <data> | Dave | Burns | c123
222 | <data> | Dave | Simpson | c123
333 | <data> | Dave | Sanchez | c123
444 | <data> | Dave | Smith | c456
results.clubs:
_id | image | name
c123 | <data> | admins
c456 | <data> | losers
这样,俱乐部数据就不会重复,从而使从服务器传输到客户端的信息的大小要小得多。然后,在客户端上显示列表时,我可以进行交叉引用以查找每个用户的俱乐部并显示适当的数据。
问题:
聚合查询中是否可以执行此操作?
我已经知道我可以在事实或其他“事实之后”查找和查询等之后进行填充-但我不想这样做。我宁愿一口气完成所有事情,因为我发现说完所有事情后,它的速度要快得多。另外,在查询中内置了分页功能以及其他类似的功能...如果我可以帮助,我不想在查询运行后填充所有丢失的数据就可以遍历结果。
有人知道这是否可以完成吗?