使用数组 Mongodb 过滤数组

Filtering Array with Array Mongodb

我在 MongoDB

中有一个这样的数据示例
{
  id: 628a8683fc489c315b330ade,
  examName : 'Final Exam',
  schedule: 
  {
    scheduleDate : '2021-10-18T17:00:00.000+00:00'
    scheduleName : 'Package Test'
    package:[
       {
         exclude_question:[1,2],
         namePackage:testing
         packageId:628a89c2fc489c315b330b01      
       }
        
    ]
  },
  question:[
    {
       id:1,
       question:'hello can u test it?'
       answer:'No'
    }
    {
       id:3,
       question:'Is it working?'
       answer:'No'
    }
    {
       id:2,
       question:'Should i repeat?'
       answer:'Yes'
    }
  ]
}

条件: 基本上在 schedule.package 可以有多个值,但我已经过滤了它所以数组中只有一个值。

现在我需要用 exclude_question 过滤问题。 exlcude_question 的值是问题的数组 id,现在我只需要显示不在 exlcude_question 中的问题 所以我期望的输出就像这样

{
  id: 628a8683fc489c315b330ade,
  examName : 'Final Exam',
  schedule: {.......},
  question:[
    {
       id:3,
       question:'Is it working?'
       answer:'No'
    }
  ]
}

它只显示 id: 3 的问题,因为它不在 exclude_question 中。我对如何从数组中的数组中获取值来过滤问题数组感到困惑。如果您有任何建议,我将非常感谢

您可以像下面这样使用聚合,

  • 你已经提到 shedule.package 总是有一个元素,所以你需要排除的数组。对于安全操作员,我们使用 $ifNull
  • $filter排除需要排除的问题
  • $unset去掉第一步设置的变量

这是代码

db.collection.aggregate([
  {
    "$addFields": {
      "exe_qus": {
        "$ifNull": [
          { "$arrayElemAt": [ "$schedule.package", 0 ] },
          []
        ]
      }
    }
  },
  {
    "$addFields": {
      "question": {
        "$filter": {
          "input": "$question",
          "cond": {
            $not: {
              $in: [ "$$this.id", "$exe_qus.exclude_question" ]
            }
          }
        }
      }
    }
  },
  {
    "$unset": "exe_qus"
  }
])

工作Mongo playground

  1. $set - 创建 exclude_questions 字段:

    1.1。 $reduce - 迭代 schedule.package 的每个文档,将 ($concatArrays) exclude_question 数组值合并到一个新数组中并 return 它。

  2. $set - 设置 question 字段的值。

    2.1。 $filter - 使用文档的 id $not $in exclude_questions 数组过滤 question 数组字段中的文档。

  3. $unset - 删除 exclude_questions 字段。

db.collection.aggregate([
  {
    $set: {
      exclude_questions: {
        $reduce: {
          input: "$schedule.package",
          initialValue: [],
          in: {
            $concatArrays: [
              "$$value",
              "$$this.exclude_question"
            ]
          }
        }
      }
    }
  },
  {
    $set: {
      question: {
        $filter: {
          input: "$question",
          cond: {
            $not: {
              $in: [
                "$$this.id",
                "$exclude_questions"
              ]
            }
          }
        }
      }
    }
  },
  {
    $unset: "exclude_questions"
  }
])

Sample Mongo Playground

这是另一种方法。

db.collection.aggregate([
  {
    "$set": {
      "question": {
        "$filter": {
          "input": "$question",
          "as": "q",
          "cond": {
            "$not": [
              {"$in": ["$$q.id", {"$first": "$schedule.package.exclude_question"}]}
            ]
          }
        }
      }
    }
  }
])

mongoplayground.net 上试用。