【问题标题】:Count number of elements to get from lookup query for nested referenced array in mongodb计算要从 mongodb 中嵌套引用数组的查找查询中获取的元素数
【发布时间】:2020-01-17 13:08:39
【问题描述】:

我有以下分类集合

{
"_id" : ObjectId("5e1d8c3ed06661d2b06a7c46"),
    "status" : "active",
    "noOfLevels" : 3,
    "levels" : [ 
        ObjectId("5e1db2237a265cfe50dfdb18"), 
        ObjectId("5e1db22b7a265cfe50dfdb19"), 
        ObjectId("5e1db23b7a265cfe50dfdb1a")
    ],
    "name" : "Fuel",
},
{
 "_id" : ObjectId("5e1d8c3ed06661d2b06a7c46"),
    "status" : "active",
    "noOfLevels" : 3,
    "levels" : [ 
        ObjectId("5e1db2237a265cfe50dfdb18"), 
        ObjectId("5e1db22b7a265cfe50dfdb19"), 
        ObjectId("5e1db23b7a265cfe50dfdb1a")
    ],
    "name" : "Feeds",
}

在上述集合级别中,_id 已被存储为以后填充的参考。

关卡集合有这个项目:-

{
 levelName: { type: String, required: true },
  levelDesc: { type: String },
  levelNo: { type: Number, required: true },
  categoryId: { type: Mongoose.Schema.Types.ObjectId, ref: 'trainingCategories', required: true },
  videoId: [{ type: Mongoose.Schema.Types.ObjectId, ref: 'trainingVideoMaster' }],
},
{
 levelName: { type: String, required: true },
  levelDesc: { type: String },
  levelNo: { type: Number, required: true },
  categoryId: { type: Mongoose.Schema.Types.ObjectId, ref: 'trainingCategories', required: true },
  videoId: [{ type: Mongoose.Schema.Types.ObjectId, ref: 'trainingVideoMaster' }],
}

我正在使用聚合和查找来查找类别集合中的项目,在我的最终结果中,我需要特定类别的每个级别上存在的 videoIds 的计数。

需要这样的最终结果:-

 {
                        name: 'How to save fuel',
                        catNo: 1,
                        noOfLevels: 3,
                        totalVideos: 4
    },
    {
                        name: 'Feeds',
                        catNo: 2,
                        noOfLevels: 3,
                        totalVideos: 3
     }

【问题讨论】:

  • 请展示您的尝试
  • @Ashh 类似这样 Cat.aggregate([ { $match: {status: 'active' }}, { $lookup: {from: 'traininglevels', localField: 'levels', foreignField: '_id', as: 'trainingLevels'} }, { "$project": { noOfLevels: 1, name: 1, catNo: 1, createdAt: 1, trainingLevels: {$sum:'$trainingLevels.videoId'} }} ]) 但我知道它不符合聚合方案。

标签: node.js mongodb aggregation-framework lookup


【解决方案1】:

您需要$unwind trainingLevels 数组使其成为对象属性,然后您可以使用.dot 表示法来获取videoId 长度。

Cat.aggregate([
  { "$match": { "status": "active" } },
  { "$lookup": {
    "from": "traininglevels",
    "let": { "levels": "$levels" },
    "pipeline": [
      { "$match": { "$expr": { "$in": ["$_id", "$$levels"] }}},
      { "$group": {
        "_id": null,
        "totalVideos": { "$sum": { "$size": "$videoId" }}
      }}
    ]
    "as": "trainingLevels"
  }},
  { "$unwind": "$trainingLevels" },
  { "$project": {
    "noOfLevels": 1,
    "name": 1,
    "catNo": 1,
    "createdAt": 1,
    "trainingLevels": "$trainingLevels.totalVideos"
  }}
])

【讨论】:

  • 在这种情况下,我得到了重复的类别:- "categories": [ { "_id": "5e1d8c3ed06661d2b06a7c46", "noOfLevels": 3, "name": "HOW TO SAVE FUEL", "catNo “:1,“totalVideos”:0 },{“_id”:“5e1d8c3ed06661d2b06a7c46”,“noOfLevels”:3,“名称”:“如何节省燃料”,“catNo”:1,“totalVideos”:5,} ,
  • 多个文档可以有相同的_id 吗?我可以看到"foreignField": "_id",这绝对意味着您与traininglevels 集合中的_id 匹配,并且对于多个文档不应该是相同的。
  • 在类别集合中,levels 被引用为 ObjectId 数组,同样,levels 将 videoIds 作为 ObjectId 数组。这里发生的事情是它返回级别集合中存在 videoId 的对象的数据。并且它没有返回 videoId 为空数组 [] 的级别的数据。
  • 而且分组也不是用这个实现的。
  • 您的答案适用于类别集合中没有级别为空数组的数据,级别为空 [] 的类别不会从查询中返回。添加这个可以解决问题:- { $unwind: { path: "$trainingLevels", preserveNullAndEmptyArrays: true } }, { "$project": { "noOfLevels": 1, "name": 1, "catNo": 1, "createdAt": 1, "totalVideos": { "$cond":{ if: { $gte: ['$trainingLevels.totalVideos', 0] }, then: "$trainingLevels.totalVideos", else: 0 }} }} ])
猜你喜欢
  • 2021-08-27
  • 1970-01-01
  • 2021-10-14
  • 2018-02-20
  • 1970-01-01
  • 2015-08-13
  • 1970-01-01
  • 2023-02-01
  • 1970-01-01
相关资源
最近更新 更多