【问题标题】:How to list only matched subdocuments in Mongoose如何在猫鼬中仅列出匹配的子文档
【发布时间】:2021-05-08 03:05:58
【问题描述】:

我是猫鼬的新手。我尝试了很多查询,但无法获得正确的结果。 我的架构如下所示:

{
 course_name: "Test 1",
 students: [
  {name: "Sam", age: 5},
  {name: "Don", age: 7}
 ]
},
{
 course_name: "Test 2",
 students: [
  {name: "Paul", age: 7}
 ]
}

在这个例子中,我有 2 个文档。每个课程文档都包含其中的学生数据。 我正在尝试查找年龄为 7 岁的所有课程中的所有学生。但在我尝试的查询中,它也返回 Sam。

这是我期待的一个例子:

{name: "Paul", age: 7},
{name: "Don", age: 7}

这就是我得到的。

{name: "Paul", age: 7},
{name: "Sam", age: 5},
{name: "Don", age: 7}

我的查询:

const getStudents = await Courses.aggregate([
    {$match: {'students.age': myAge}},
    {$unwind: '$students'},
    {$project: {name: '$students.name', age: '$students.age'}}
  ]);

感谢您的宝贵时间

【问题讨论】:

    标签: mongodb mongoose


    【解决方案1】:

    一个常见的错误是认为如果你匹配一个嵌套值(在本例中为students.age)你会得到你想要的嵌套值,但它不是这样工作的。

    您在$unwind 之前执行$match 查询,因此您将所有存在任何对象的文档放入students 数组中,其中age 为7。也就是说,整个document1 传递到下一阶段。具有两个值的数组students 进入下一个 tsage,因为其中一个符合条件,然后对象被匹配。

    所以,更清楚地说,你正在做一个$match 阶段,你说:“给我所有存在的文件,其中存在一个 7 岁的学生”。然后,第一个文档匹配条件,因为其中一个学生匹配过滤器,并返回整个文档,而不仅仅是数组中匹配的对象。

    你可以在展开后进行匹配,你会得到想要的输出。

    例如here

    【讨论】:

      【解决方案2】:

      @J.F.很好地解释了为什么您的方法不正确。无论如何,我想向您展示如何使用 $filter 获得相同的结果。

      根据指定的数组选择要返回的子集 健康)状况。返回一个仅包含与 健康)状况。返回的元素按照原来的顺序排列。

      db.collection.aggregate({
        $addFields: {
          students: {
            $filter: {
              input: "$students",
              as: "student",
              cond: {
                $eq: [
                  "$$student.age",
                  7
                ]
              }
            }
          }
        }
      })
      

      结果:

      [
        {
          "_id": ObjectId("5a934e000102030405000000"),
          "course_name": "Test 1",
          "students": [
            {
              "age": 7,
              "name": "Don"
            }
          ]
        },
        {
          "_id": ObjectId("5a934e000102030405000001"),
          "course_name": "Test 2",
          "students": [
            {
              "age": 7,
              "name": "Paul"
            }
          ]
        }
      ]
      

      【讨论】:

        猜你喜欢
        • 2016-04-08
        • 2017-11-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-07
        • 1970-01-01
        • 2019-06-06
        相关资源
        最近更新 更多