MongoDB mongoose聚合查询以返回单独对象中的子文档

时间:2018-08-29 17:38:17

标签: mongodb mongoose

给出以下模式:

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 

这样,俱乐部数据就不会重复,从而使从服务器传输到客户端的信息的大小要小得多。然后,在客户端上显示列表时,我可以进行交叉引用以查找每个用户的俱乐部并显示适当的数据。

问题:

聚合查询中是否可以执行此操作?

我已经知道我可以在事实或其他“事实之后”查找和查询等之后进行填充-但我不想这样做。我宁愿一口气完成所有事情,因为我发现说完所有事情后,它的速度要快得多。另外,在查询中内置了分页功能以及其他类似的功能...如果我可以帮助,我不想在查询运行后填充所有丢失的数据就可以遍历结果。

有人知道这是否可以完成吗?

0 个答案:

没有答案