MongoDB $switch 运算符介绍

$switch 运算符是 MongoDB 中的条件语句运算符之一,它可以基于给定的表达式值执行多个不同的操作,类似于编程语言中的 switch 语句。使用 $switch 运算符可以根据条件动态地生成不同的结果。

语法

$switch 运算符的语法如下:

{
  $switch: {
    branches: [
      {
        case: <expression>,
        then: <expression>
      },
      {
        case: <expression>,
        then: <expression>
      },
      ...
    ],
    default: <expression>
  }
}
  • branches:一个包含多个分支的数组,每个分支包括 case 和 then 两个字段。
    • case:一个表达式,用于判断是否满足该分支的条件。
    • then:一个表达式,用于指定满足该分支条件时要执行的操作。
  • default:一个表达式,用于指定当没有分支满足条件时要执行的操作。

使用场景

$switch 运算符通常用于需要根据不同的条件动态生成结果的场景。例如:

  • 根据不同的条件对文档进行分类。
  • 根据文档中的字段值返回不同的结果。

示例

示例 1:根据不同的条件分类

假设我们有一个集合 fruits,其中包含多个水果的信息,包括水果名称、产地、颜色等。现在,我们需要根据水果的颜色进行分类,将同一颜色的水果放在一起。

假设集合 fruits 中有以下文档:

{ "_id": 1, "name": "apple", "color": "red", "origin": "China" }
{ "_id": 2, "name": "banana", "color": "yellow", "origin": "Thailand" }
{ "_id": 3, "name": "grape", "color": "red", "origin": "USA" }
{ "_id": 4, "name": "orange", "color": "orange", "origin": "USA" }
{ "_id": 5, "name": "watermelon", "color": "green", "origin": "USA" }

我们可以使用 $switch 运算符将同一颜色的水果放在一起,可以使用以下查询语句:

db.fruits.aggregate([
  {
    $project: {
      name: 1,
      color: 1,
      origin: 1,
      fruit_type: {
        $switch: {
          branches: [
            { case: { $eq: ["$color", "red"] }, then: "red_fruit" },
            { case: { $eq: ["$color", "yellow"] }, then: "yellow_fruit" },
            { case: { $eq: ["$color", "orange"] }, then: "orange_fruit" },
            { case: { $eq: ["$color", "green"] }, then: "green_fruit" }
          ],
          default: "unknown"
        }
      }
    }
  }
])

执行以上查询语句后,返回的结果如下:

{ "_id": 1, "name": "apple", "color": "red", "origin": "China", "fruit_type": "red_fruit" }
{ "_id": 2, "name": "banana", "color": "yellow", "origin": "Thailand", "fruit_type": "yellow_fruit" }
{ "_id": 3, "name": "grape", "color": "red", "origin": "USA", "fruit_type": "red_fruit" }
{ "_id": 4, "name": "orange", "color": "orange", "origin": "USA", "fruit_type": "orange_fruit" }
{ "_id": 5, "name": "watermelon", "color": "green", "origin": "USA", "fruit_type": "green_fruit" }

以上查询语句中, $switch 运算符的 branches 属性是一个包含多个 case 和 then 子属性的数组,用于匹配不同的条件。如果没有匹配的条件,则会返回 default 属性的值。在这个例子中,我们将水果的颜色作为 case 进行匹配,并将匹配到的结果保存在 fruit_type 字段中。

示例 2:使用 $switch 运算符进行条件计算

假设我们有一个集合 users,其中包含多个用户的信息,包括用户名、性别、年龄等。现在,我们需要根据用户的年龄进行分类,并计算不同年龄段的人数。可以使用 $switch 运算符来实现。

假设集合 users 中有以下文档:

{ "_id": 1, "username": "Tom", "gender": "male", "age": 20 }
{ "_id": 2, "username": "Jane", "gender": "female", "age": 25 }
{ "_id": 3, "username": "John", "gender": "male", "age": 30 }
{ "_id": 4, "username": "Lucy", "gender": "female", "age": 35 }
{ "_id": 5, "username": "Jack", "gender": "male", "age": 40 }

现在,我们需要根据用户的年龄进行分类,并计算不同年龄段的人数,具体实现如下:

db.users.aggregate([
  {
    $project: {
      ageGroup: {
        $switch: {
          branches: [
            {
              case: { $lt: ["$age", 20] },
              then: "Under 20"
            },
            {
              case: { $and: [{ $gte: ["$age", 20] }, { $lt: ["$age", 30] }] },
              then: "20-29"
            },
            {
              case: { $and: [{ $gte: ["$age", 30] }, { $lt: ["$age", 40] }] },
              then: "30-39"
            },
            {
              case: { $gte: ["$age", 40] },
              then: "40 and above"
            }
          ],
          default: "Unknown"
        }
      }
    }
  },
  {
    $group: {
      _id: "$ageGroup",
      count: { $sum: 1 }
    }
  }
])

解析:

首先,使用 $project 阶段将文档转换为 ageGroup 字段,该字段通过 $switch 运算符进行计算。 $switch 运算符使用 branches 数组指定多个条件,每个条件通过 case 属性指定,then 属性指定该条件下计算的值。default 属性指定默认值,如果所有条件都不满足,则使用默认值。

接下来,使用 $group 阶段对 ageGroup 字段进行分组,并使用 $sum 运算符计算每个分组中文档的数量,最终得到不同年龄段的人数。

运行以上代码,可以得到以下结果:

{ "_id": "20-29", "count": 2 }
{ "_id": "30-39", "count": 2 }
{ "_id": "40 and above", "count": 1 }

以上结果表示,年龄在 20 到 29 岁之间的用户有 2 个,年龄在 30 到 39 岁之间的用户有 2 个,年龄在 40 岁及以上的用户有 1 个。

结论

通过本文对 $switch 运算符的介绍和示例,我们可以看出 $switch 运算符在 MongoDB 中的强大功能。它可以根据不同的条件执行不同的操作,可以实现复杂的数据分类和计算,提高数据处理的效率和精度。同时,需要注意在使用 $switch 运算符时要注意语法的正确性和使用场景的合理性,以避免不必要的错误和性能损失。