我想让mongodb聚合查找从下面的用户集合中连接程序数组module_id和module_attemps键

tv6aics1  于 2023-03-01  发布在  Go
关注(0)|答案(1)|浏览(67)

这是电流收集

// collection: users
{
    "_id" : ObjectId("63ab0d0ed5e1b9566e0a2632"),
    "created_at" : ISODate("2022-12-27T20:49:42.350+05:30"),
    "programs" : [
        {
            "program_id" : "5c1a01c6079288177e793c82",
            "modules" : [
                {
                    "module_id" : "5d5e9d990792882b250ecbf2",
                    "module_instance_id" : "63ab0dedd5e1b9566e0a2638"
                },
                {
                    "module_id" : "5d5671e9079288617b1eaf72",
                    "module_instance_id" : "63abf24b8c5554a06f0dcf52"
                }
            ]
        },
        {
            "program_id" : "5c401f7307928872bf7ed303",
            "modules" : [
                {
                    "module_id" : "5d4bffd70792883e8b16b066",
                    "module_instance_id" : "63ac4ccd9273aa285f011772"
                },
                {
                    "module_id" : "5d5684ff0792886b371d9dc2",
                    "module_instance_id" : "63ad866b32b504b0340449d2"
                }
            ]
        }
    ],
    "module_attempts" : {
        "5d5e9d990792882b250ecbf2" : { //module_id
            "63ab0dedd5e1b9566e0a2638" : { //module_instance_id
                "start_date" : "2022-12-27 15:33:53",
                "module_instance_id" : "63ab0dedd5e1b9566e0a2638"
            }
        },
        "5d5671e9079288617b1eaf72" : {
            "63abf24b8c5554a06f0dcf52" : {
                "start_date" : "2023-01-02 11:11:17",
                "module_instance_id" : "63abf24b8c5554a06f0dcf52"
            }
        },
        "5d5684ff0792886b371d9dc2" : {
            "63ad866b32b504b0340449d2" : {
                "start_date" : "2023-01-02 13:57:27",
                "module_instance_id" : "63ad866b32b504b0340449d2"
            }
        }
    }
}

module_attempts数组两个键是module_idmodule_instance_id。我正在尝试执行以下任务和活动结果数组。
1.将程序users.programs.modules合并到一个数组中,该数组包含用户的所有模块2.迭代新的模块数组,并通过使用模块“module_instance_id”与module_attempts数组合并

我需要得到的结果数组:

{
    "_id" : ObjectId("63ab0d0ed5e1b9566e0a2632"),
    "module_instance_id" : "63ab0dedd5e1b9566e0a2638",
    "module_id" : "5d5e9d990792882b250ecbf2",
    "start_date" : "2022-12-27 15:33:53",
},
{
    "_id" : ObjectId("63ab0d0ed5e1b9566e0a2632"),
    "module_instance_id" : "63abf24b8c5554a06f0dcf52",
    "module_id" : "5d5671e9079288617b1eaf72",
    "start_date" : "2023-01-02 11:11:17",
}
{
....
}

我尝试了以下功能

db.users.aggregate([
     { "$match": { "_id": ObjectId("63ab0d0ed5e1b9566e0a2632") }},
  {
    $unwind: "$programs"
  },
  {
    $unwind: "$programs.modules"
  },
  {
    $lookup: {
      from: "users",
      localField: "programs.modules.module_id",
      foreignField: "module_attempts",
      as: "module_attempts"
    }
  },
  {
    $unwind: "$module_attempts"
  },
  {
    $addFields: {
      "programs.modules.module_attempts": "$module_attempts.module_attempts"
    }
  },
  {
    $group: {
      _id: "$_id",
      created_at: { $first: "$created_at" },
      programs: { $push: "$programs.modules" },
      module_attempts: { $first: "$module_attempts" }
    }
  }
])

但是结果变空了。知道如何从这个集合中得到上面的结果吗?

kpbwa7wx

kpbwa7wx1#

我认为模型结构需要根据最佳实践进行修改,这也将提高查询性能。
但是它可以用$replaceWith来完成,并且查询也将相当长。
注意:* 自version 4.2起支持$replaceWith *
解决方案:MONGO_PLAYGROUND
带解释的代码,

db.users.aggregate([
  {
    $match: {
      _id: ObjectId("63ab0d0ed5e1b9566e0a2632"),
    },
  },
  {
    $unwind: "$programs",
  },
  {
    $unwind: "$programs.modules",
  },

  // need to split the module_attempts an array 
  // so we can compare the Id value 

  {
    $project: {
      start_date: "$created_at",
      programs: "$programs.modules",
      tempModules: {
        $objectToArray: "$module_attempts",
      },
    },
  },

  // make the $tempModules to an Object
  {
    $unwind: "$tempModules",
  },
  
  // we use $cond (if-else-then) => required
  // in this stage, there will be an Object with module_instance_id: null

  {
    $replaceWith: {
      _id: "$_id",
      start_date: "$start_date",
      module_id: "$programs.module_id",
      module_instance_id: {
        $cond: {
          if: {
            $eq: ["$programs.module_id", "$tempModules.k"],
          },
          then: "$programs.module_instance_id",
          else: null,
        },
      },
    },
  },

  // remove module_instance_id with null value.
  {
    $match: {
      module_instance_id: {
        $ne: null,
      },
    },
  },
]);

MONGO_PLAYGROUND

相关问题