MongoDB 中$Match(聚合)阶段的使用

Mehvish Ashiq 2023年1月30日
  1. 在 MongoDB 中使用 $match(聚合)阶段
  2. 在 MongoDB 中将 $match 与比较运算符一起使用
  3. 在 MongoDB 中使用 $match$project 阶段
  4. 在 MongoDB 中使用 $match$and 运算符
  5. 在 MongoDB 中使用 $match$or 运算符
  6. 在 MongoDB 中使用 $match 聚合与 $group
  7. 在 MongoDB 中使用 $match 聚合与 $month$year
MongoDB 中$Match(聚合)阶段的使用

本教程简要讨论了 $match 聚合阶段,并演示了考虑不同场景的 $match 阶段。

在 MongoDB 中使用 $match(聚合)阶段

$match 阶段让我们过滤与指定条件(或条件集)匹配的文档(记录)。只有匹配的文档才会进入管道的下一阶段。

让我们准备一个包含一些文档的集合,以通过代码示例进行学习。

示例代码:

db.createCollection('employee');
db.employee.insertMany([
    {
        "emp_code": "ma001",
        "emp_age": 30,
        "emp_grade": 18,
        "emp_joindate": ISODate('2012-08-16T00:00:00Z')
    },
    {
        "emp_code": "tc002",
        "emp_age": 40,
        "emp_grade":19,
        "emp_joindate": ISODate('2011-08-16T00:00:00Z')
    },
    {
        "emp_code": "km003",
        "emp_age": 45,
        "emp_grade":18,
        "emp_joindate": ISODate('2012-08-26T00:00:00Z')
    },
    {
        "emp_code": "ar004",
        "emp_age": 32,
        "emp_grade":20,
        "emp_joindate": ISODate('2014-10-06T00:00:00Z')
    },
    {
        "emp_code": "za005",
        "emp_age": 45,
        "emp_grade":20,
        "emp_joindate": ISODate('2014-03-11T00:00:00Z')
    },
    {
        "emp_code": "ka006",
        "emp_age": 35,
        "emp_grade": 22,
        "emp_joindate": ISODate('2018-06-16T00:00:00Z')
    }
]);
db.employee.find().pretty();

输出:

{
        "_id" : ObjectId("629c376ca4cfbd782e90d5a0"),
        "emp_code" : "ma001",
        "emp_age" : 30,
        "emp_grade" : 18,
        "emp_joindate" : ISODate("2012-08-16T00:00:00Z")
}
{
        "_id" : ObjectId("629c376ca4cfbd782e90d5a1"),
        "emp_code" : "tc002",
        "emp_age" : 40,
        "emp_grade" : 19,
        "emp_joindate" : ISODate("2011-08-16T00:00:00Z")
}
{
        "_id" : ObjectId("629c376ca4cfbd782e90d5a2"),
        "emp_code" : "km003",
        "emp_age" : 45,
        "emp_grade" : 18,
        "emp_joindate" : ISODate("2012-08-26T00:00:00Z")
}
{
        "_id" : ObjectId("629c376ca4cfbd782e90d5a3"),
        "emp_code" : "ar004",
        "emp_age" : 32,
        "emp_grade" : 20,
        "emp_joindate" : ISODate("2014-10-06T00:00:00Z")
}
{
        "_id" : ObjectId("629c376ca4cfbd782e90d5a4"),
        "emp_code" : "za005",
        "emp_age" : 45,
        "emp_grade" : 20,
        "emp_joindate" : ISODate("2014-03-11T00:00:00Z")
}
{
        "_id" : ObjectId("629c376ca4cfbd782e90d5a5"),
        "emp_code" : "ka006",
        "emp_age" : 35,
        "emp_grade" : 22,
        "emp_joindate" : ISODate("2018-06-16T00:00:00Z")
}

一旦我们完成创建集合并在其中插入文档,我们就可以继续使用 $match 聚合阶段来学习。考虑到各种情况,让我们使用 $match 阶段来更好地学习。

在 MongoDB 中将 $match 与比较运算符一起使用

示例代码:

db.employee.aggregate([
   {
       $match:{ "emp_age": { $gt:35 }}
   }
]).pretty();

输出:

{
        "_id" : ObjectId("629c376ca4cfbd782e90d5a1"),
        "emp_code" : "tc002",
        "emp_age" : 40,
        "emp_grade" : 19,
        "emp_joindate" : ISODate("2011-08-16T00:00:00Z")
}
{
        "_id" : ObjectId("629c376ca4cfbd782e90d5a2"),
        "emp_code" : "km003",
        "emp_age" : 45,
        "emp_grade" : 18,
        "emp_joindate" : ISODate("2012-08-26T00:00:00Z")
}
{
        "_id" : ObjectId("629c376ca4cfbd782e90d5a4"),
        "emp_code" : "za005",
        "emp_age" : 45,
        "emp_grade" : 20,
        "emp_joindate" : ISODate("2014-03-11T00:00:00Z")
}

在这里,我们只得到那些 emp_age(员工年龄)大于 35 的文档。pretty() 函数什么都不做,只是以有组织的方式显示输出。

在 MongoDB 中使用 $match$project 阶段

示例代码:

db.employee.aggregate([
  {
     $match: {
        "emp_age": { $gt:35 }
     }
  },
  {
     $project:{
        "_id": 0,
        "emp_code": 1,
        "emp_age": 1
     }
  }
]);

输出:

{ "emp_code" : "tc002", "emp_age" : 40 }
{ "emp_code" : "km003", "emp_age" : 45 }
{ "emp_code" : "za005", "emp_age" : 45 }

此代码片段类似于前面的示例,但额外使用了 $project 阶段,该阶段指定应从查询中返回哪些字段。在 $project 阶段使用 10 分别表示该字段的包含和抑制。

请记住,第一阶段返回的文件只会在下一阶段处理。我们从所有那些 emp_age(员工年龄)大于 35 的文档中获取 emp_codeemp_age

在 MongoDB 中使用 $match$and 运算符

示例代码:

db.employee.aggregate([
  {
      $match:{
          $and: [
              { "emp_age": {$gte:32 }},
              { "emp_grade": {$gt: 20}}
          ]
      }
  },
  {
      $project:{
          "_id": 0,
          "emp_age": 1,
          "emp_grade": 1
      }
  }
]);

输出:

{ "emp_age" : 35, "emp_grade" : 22 }

此示例从那些 emp_age 大于或等于 32 且 emp_grade 大于 20 的文档返回 emp_ageemp_grade。请记住,生成的文档必须同时满足这两个条件。

在 MongoDB 中使用 $match$or 运算符

示例代码:

db.employee.aggregate([
  {
      $match:{
           $or: [
               { "emp_age": {$gte:32 }},
               { "emp_grade": {$gt: 20}}
           ]
       }
  },
  {
      $project:{
          "_id": 0,
          "emp_age": 1,
          "emp_grade": 1
      }
  }
]);

输出:

{ "emp_age" : 40, "emp_grade" : 19 }
{ "emp_age" : 45, "emp_grade" : 18 }
{ "emp_age" : 32, "emp_grade" : 20 }
{ "emp_age" : 45, "emp_grade" : 20 }
{ "emp_age" : 35, "emp_grade" : 22 }

此代码片段与上一个类似,但我们在这里使用 $or 运算符。在这里,生成的文档必须满足至少一个条件或同时满足这两个条件。

在 MongoDB 中使用 $match 聚合与 $group

示例代码:

db.employee.aggregate([
  {
      $match:{
           $or: [
               { "emp_age": {$gte:32 }},
               { "emp_grade": {$gt: 20}}
           ]
       }
  },
  {
      $group:{
         _id: '$emp_grade',
         Employees: { $sum: 1 } }
  }
]);

输出:

{ _id: 18, Employees: 1 }
{ _id: 20, Employees: 2 }
{ _id: 19, Employees: 1 }
{ _id: 22, Employees: 1 }

首先,我们得到那些 emp_age 大于或等于 32、emp_grade 大于 20 或两者兼有的文档。满足条件的文档也将包含在结果集中。

这些生成的文档将移至下一阶段,即我们用来对文档进行分组的 $group。员工的等级。在 $group 阶段,我们将 emp_grade 的值保存在 _id 中,并将该特定等级的计数保存在 Employees 变量中。

在 MongoDB 中使用 $match 聚合与 $month$year

示例代码:

db.employee.aggregate([
  {
      $match: {
          "emp_joindate" : {
              $gte:ISODate('2012-01-01'),
              $lt: ISODate('2014-12-30')
          }
      }
  },
  {
      $project:{
          "_id": 0,
          "emp_code": 1,
          "emp_age": 1,
          "emp_grade": 1,
          "new_created": {
               "year" : {"$year" : "$emp_joindate"},
               "month" : {"$month" : "$emp_joindate"}
           }
      }
  },
  {
      $group:{
          _id: "$new_created",
          EmployeesCount:{ $sum:1 }
      }
  }

]);

输出:

{ _id: { year: 2012, month: 8 }, EmployeesCount: 2 }
{ _id: { year: 2014, month: 10 }, EmployeesCount: 1 }
{ _id: { year: 2014, month: 3 }, EmployeesCount: 1 }

这个最终的代码片段包含本教程前面解释的所有概念。在这里,我们使用下面解释的三个阶段。

首先,我们使用 $match 聚合阶段来获取 emp_joindate 大于或等于 2012-01-01 且小于 2014-12-30 的所有文档。就 ISODate() 函数而言,它是一个帮助函数,用于包装原生 JavaScript DATE 对象。

每当我们在 Mongo shell 上使用 ISODate() 构造函数时,它都会返回 JavaScript 的 DATE 对象。 $match 阶段的结果文档被发送到 $project 阶段。

$project 聚合阶段,我们指定应该返回文档的哪些字段。此外,我们分别使用 $year$monthemp_joindate 中提取年份和月份。

然后,我们将提取的月份和年份保存在 new_created 变量中。这个阶段的结果被传递到 $group 聚合阶段。

我们在 $group 阶段对文档进行分组,以了解在特定月份和年份中任命了多少员工。

作者: Mehvish Ashiq
Mehvish Ashiq avatar Mehvish Ashiq avatar

Mehvish Ashiq is a former Java Programmer and a Data Science enthusiast who leverages her expertise to help others to learn and grow by creating interesting, useful, and reader-friendly content in Computer Programming, Data Science, and Technology.

LinkedIn GitHub Facebook

相关文章 - MongoDB Match