在聚合管道的项目阶段排除嵌套对象 属性 时遇到问题

Having trouble in excluding nested object property in project stage in aggregation pipeline

我有一个聚合查询,其中 returns 问题数组根据文档类型具有不同的架构。文件格式如下。有些问题可能看起来像这样

{
   "_id": "ID01",
   "Description": "1.Any Question?",
   "answer": { "option05": "E. " },
   "options": {
               "option01": "A.",
               "option02": "B.",
               "option03": "C.",
               "option04": "D.",
               "option05": "E."
              },
   "type": "1",
   "score": 10
},
    

部分问题结构如下

{
  "_id": "ID02",
  "Description": "Question Description.",
  "emq": {
           "emq3": {
                     "answer": "option12",
                     "explanation": "",
                     "question": "1 Any Qstn?"
                   },
           "emq4": {
                     "answer": "option03",
                     "explanation": "",
                     "question": "2 Any Qstn?"
                   },
           "emq5": {
                     "answer": "option06",
                     "explanation": "",
                     "question": "3 Any Qstn?"
                    }
            },
                               
  "options": {
               "option01": "",
               "option02": "",
               "option03": "",
               "option04": "",
             },
  "type": "2",
  "score": 100
},

我使用了以下聚合管道来隐藏问题中的答案,(相关架构已迁移,我无法更改其结构)

聚合管道

{
          $lookup: {
            from: 'questions',
            let: {
              question_id: { $toObjectId: '$qId' },
              score: '$score',
            },
            pipeline: [
              {
                $match: {
                  $expr: {
                    $eq: ['$_id', '$$question_id'],
                  },
                },
              },
              {
                $project: {
                  answer: {
                    $cond: {
                      if: { $eq: ['$type', '1'] },
                      then: 0,
                      else: {
                        $cond: {
                          if: { $eq: ['$type', '3'] },
                          then: {
                            $cond: {
                              if: {
                                emq: {
                                  regex: /^emq\d+$/,
                                },
                              },
                              then: 0,
                              else: 1,
                            },
                          },
                          else: 1,
                        },
                      },
                    },
                  },
                  Description: 1,
                  options: 1,
                  type: 1,
                  emq: 1,
                  score: 1,
                },
              },
          }

它适用于类型 1 的问题,但不幸的是我无法隐藏类型 2 的答案,因为它们不仅在 'emq' 对象中而且也在嵌套的 'emq3' 对象中在字符串 'emq' 的末尾使用动态数字,我应用了正则表达式,但不知何故我无法在 emq3 对象中投影答案,是否有实现以下结果来隐藏两个问题的答案

{
   "_id": "ID01",
   "Description": "1.Any Question?",
   "options": {
               "option01": "A.",
               "option02": "B.",
               "option03": "C.",
               "option04": "D.",
               "option05": "E."
              },
   "type": "1",
   "score": 10
},
{
      "_id": "ID02",
      "Description": "Question Description.",
      "emq": {
               "emq3": {
                         "question": "1 Any Qstn?"
                       },
               "emq4": {
                         "question": "2 Any Qstn?"
                       },
               "emq5": {
                         "question": "3 Any Qstn?"
                        }
                },
                                   
      "options": {
                   "option01": "",
                   "option02": "",
                   "option03": "",
                   "option04": "",
                 },
      "type": "2",
      "score": 100
    },

您可以在聚合管道中执行以下操作:

  1. 使用$objectToArray
  2. 将对象emq转换为k-v元组数组
  3. $project 删除字段 answerexplanation
  4. convert the array emq`回对象
db.collection.aggregate([
  {
    "$addFields": {
      "emq": {
        "$objectToArray": "$emq"
      }
    }
  },
  {
    "$project": {
      "emq.v.answer": false,
      "emq.v.explanation": false,
      "answer": false
    }
  },
  {
    "$addFields": {
      "emq": {
        "$arrayToObject": "$emq"
      }
    }
  },
  {
    "$addFields": {
      emq: {
        "$cond": {
          "if": {
            $eq: [
              "$emq",
              null
            ]
          },
          "then": "$$REMOVE",
          "else": "$emq"
        }
      }
    }
  }
])

这里是Mongo playground供大家参考。