MongoDB 数据转换

MongoDBMongoDBBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

介绍

在本实验中,你将学习如何使用基本的聚合操作来转换 MongoDB 数据。实验涵盖了五个关键步骤:选择输出字段、重命名字段、计算新字段、格式化输出以及过滤结果。通过这些步骤,你将获得实际操作经验,学会如何重塑和分析存储在 MongoDB 集合中的数据。实验提供了一个书籍的示例数据集,并演示了如何利用聚合管道(aggregation pipeline)来提取、操作并以更有意义的方式呈现数据。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL mongodb(("MongoDB")) -.-> mongodb/AggregationOperationsGroup(["Aggregation Operations"]) mongodb(("MongoDB")) -.-> mongodb/BasicOperationsGroup(["Basic Operations"]) mongodb(("MongoDB")) -.-> mongodb/QueryOperationsGroup(["Query Operations"]) mongodb(("MongoDB")) -.-> mongodb/DataTypesGroup(["Data Types"]) mongodb(("MongoDB")) -.-> mongodb/ArrayandEmbeddedDocumentsGroup(["Array and Embedded Documents"]) mongodb/BasicOperationsGroup -.-> mongodb/insert_document("Insert Document") mongodb/QueryOperationsGroup -.-> mongodb/query_with_conditions("Query with Conditions") mongodb/QueryOperationsGroup -.-> mongodb/project_fields("Project Fields") mongodb/DataTypesGroup -.-> mongodb/use_numeric_data_types("Use Numeric Data Types") mongodb/DataTypesGroup -.-> mongodb/work_with_array_data_types("Work with Array Data Types") mongodb/ArrayandEmbeddedDocumentsGroup -.-> mongodb/query_embedded_documents("Query Embedded Documents") mongodb/AggregationOperationsGroup -.-> mongodb/aggregate_group_totals("Aggregate Group Totals") subgraph Lab Skills mongodb/insert_document -.-> lab-422094{{"MongoDB 数据转换"}} mongodb/query_with_conditions -.-> lab-422094{{"MongoDB 数据转换"}} mongodb/project_fields -.-> lab-422094{{"MongoDB 数据转换"}} mongodb/use_numeric_data_types -.-> lab-422094{{"MongoDB 数据转换"}} mongodb/work_with_array_data_types -.-> lab-422094{{"MongoDB 数据转换"}} mongodb/query_embedded_documents -.-> lab-422094{{"MongoDB 数据转换"}} mongodb/aggregate_group_totals -.-> lab-422094{{"MongoDB 数据转换"}} end

选择输出字段

在这一步骤中,我们将学习如何使用 MongoDB 的聚合管道(aggregation pipeline)来选择和转换输出字段。聚合是 MongoDB 中处理和数据分析的强大方式。

首先,让我们启动 MongoDB shell:

mongosh

接下来,创建一个用于操作的书籍示例集合:

use bookstore

db.books.insertMany([
    {
        title: "MongoDB Basics",
        author: "Jane Smith",
        price: 29.99,
        pages: 250,
        categories: ["Database", "Programming"]
    },
    {
        title: "Python Deep Dive",
        author: "John Doe",
        price: 39.99,
        pages: 450,
        categories: ["Programming", "Python"]
    },
    {
        title: "Data Science Handbook",
        author: "Alice Johnson",
        price: 49.99,
        pages: 600,
        categories: ["Data Science", "Programming"]
    }
])

现在,使用聚合管道选择特定的输出字段:

db.books.aggregate([
  {
    $project: {
      _id: 0,
      bookTitle: "$title",
      bookAuthor: "$author"
    }
  }
]);

示例输出:

[
  { bookTitle: 'MongoDB Basics', bookAuthor: 'Jane Smith' },
  { bookTitle: 'Python Deep Dive', bookAuthor: 'John Doe' },
  { bookTitle: 'Data Science Handbook', bookAuthor: 'Alice Johnson' }
]

让我们分解一下我们所做的操作:

  • $project 是一个聚合阶段,用于重塑文档
  • _id: 0 排除了默认的 MongoDB 文档 ID
  • bookTitle: "$title"title 字段重命名为 bookTitle
  • bookAuthor: "$author"author 字段重命名为 bookAuthor

字段名称前的 $ 符号告诉 MongoDB 使用该字段的值。

重命名字段

在这一步骤中,我们将探索使用 MongoDB 聚合管道(aggregation pipeline)的更高级字段重命名技术。我们将基于上一步中创建的书籍集合进行操作。

让我们继续在 MongoDB shell 中操作:

mongosh

首先,切换到我们的 bookstore 数据库:

use bookstore

现在,我们将使用更复杂的 $project 阶段来重命名和转换多个字段:

db.books.aggregate([
  {
    $project: {
      _id: 0,
      bookInfo: {
        name: "$title",
        writer: "$author",
        bookLength: "$pages",
        pricing: "$price"
      },
      genres: "$categories"
    }
  }
]);

示例输出:

[
  {
    bookInfo: {
      name: 'MongoDB Basics',
      writer: 'Jane Smith',
      bookLength: 250,
      pricing: 29.99
    },
    genres: [ 'Database', 'Programming' ]
  },
  // ... 其他书籍文档
]

让我们分解一下重命名技术:

  • 我们创建了一个嵌套对象 bookInfo,其中包含重命名的字段
  • name 替换了 title
  • writer 替换了 author
  • bookLength 替换了 pages
  • pricing 替换了 price
  • 我们还将 categories 保留为 genres

你也可以使用 $rename 阶段来进行更简单的字段重命名:

db.books.aggregate([
  {
    $rename: {
      title: "bookName",
      author: "bookWriter"
    }
  }
]);

这个阶段会直接在原始文档中重命名字段。

计算新字段

在这一步骤中,我们将学习如何使用 MongoDB 的聚合管道(aggregation pipeline)通过执行计算来创建新字段。我们将继续使用 bookstore 数据库进行操作。

首先,启动 MongoDB shell:

mongosh

切换到 bookstore 数据库:

use bookstore

我们将使用 $addFields 阶段来创建新的计算字段:

db.books.aggregate([
  {
    $addFields: {
      totalValue: { $multiply: ["$price", 1.1] },
      discountedPrice: { $multiply: ["$price", 0.9] },
      pageCategories: {
        $concat: [
          { $toString: "$pages" },
          " page ",
          { $arrayElemAt: ["$categories", 0] }
        ]
      }
    }
  }
]);

示例输出:

[
  {
    _id: ObjectId("..."),
    title: "MongoDB Basics",
    author: "Jane Smith",
    price: 29.99,
    pages: 250,
    categories: ["Database", "Programming"],
    totalValue: 32.989,
    discountedPrice: 26.991,
    pageCategories: "250 page Database"
  },
  // ... 其他书籍文档
]

让我们分解一下这些计算:

  • totalValue:将价格乘以 1.1(10% 的加价)
  • discountedPrice:将价格乘以 0.9(10% 的折扣)
  • pageCategories:使用 $concat 将页数与第一个类别组合在一起

我们还可以执行更复杂的计算。让我们根据页数计算书籍评级:

db.books.aggregate([
  {
    $addFields: {
      bookRating: {
        $switch: {
          branches: [
            { case: { $lt: ["$pages", 300] }, then: "Short Book" },
            { case: { $lt: ["$pages", 500] }, then: "Medium Book" }
          ],
          default: "Long Book"
        }
      }
    }
  }
]);

这个示例使用 $switch 根据书籍的页数对其进行分类。

格式化输出

在这一步骤中,我们将探索使用 MongoDB 聚合管道(aggregation pipeline)来格式化和转换输出的各种技术。我们将继续使用 bookstore 数据库进行操作。

首先,启动 MongoDB shell:

mongosh

切换到 bookstore 数据库:

use bookstore

首先,使用 $toUpper$toLower 来格式化文本字段:

db.books.aggregate([
  {
    $project: {
      _id: 0,
      titleUpperCase: { $toUpper: "$title" },
      authorLowerCase: { $toLower: "$author" }
    }
  }
]);

示例输出:

[
  {
    titleUpperCase: 'MONGODB BASICS',
    authorLowerCase: 'jane smith'
  },
  // ... 其他书籍文档
]

接下来,使用 $round 格式化数值并创建格式化的价格字符串:

db.books.aggregate([
  {
    $project: {
      _id: 0,
      title: 1,
      roundedPrice: { $round: ["$price", 1] },
      formattedPrice: {
        $concat: ["$", { $toString: { $round: ["$price", 2] } }]
      }
    }
  }
]);

示例输出:

[
  {
    title: 'MongoDB Basics',
    roundedPrice: 30,
    formattedPrice: '$29.99'
  },
  // ... 其他书籍文档
]

我们还可以格式化数组并创建复杂的字符串表示:

db.books.aggregate([
  {
    $project: {
      _id: 0,
      title: 1,
      categoriesSummary: {
        $reduce: {
          input: "$categories",
          initialValue: "",
          in: {
            $concat: [
              "$$value",
              { $cond: [{ $eq: ["$$value", ""] }, "", ", "] },
              "$$this"
            ]
          }
        }
      }
    }
  }
]);

示例输出:

[
  {
    title: 'MongoDB Basics',
    categoriesSummary: 'Database, Programming'
  },
  // ... 其他书籍文档
]

最后一个示例使用 $reduce 将数组元素连接成一个逗号分隔的字符串。

过滤结果

在这最后一步中,我们将探索使用 MongoDB 聚合管道(aggregation pipeline)的各种过滤技术。我们将继续使用 bookstore 数据库来演示不同的结果过滤方式。

首先,启动 MongoDB shell:

mongosh

切换到 bookstore 数据库:

use bookstore

首先,使用简单的比较运算符过滤书籍:

db.books.aggregate([
  {
    $match: {
      price: { $gt: 30 },
      pages: { $lt: 500 }
    }
  }
]);

此查询过滤满足以下条件的书籍:

  • 价格大于 30
  • 页数少于 500

示例输出:

[
  {
    _id: ObjectId("..."),
    title: "Python Deep Dive",
    author: "John Doe",
    price: 39.99,
    pages: 450,
    categories: ["Programming", "Python"]
  }
]

接下来,使用更复杂的数组操作进行过滤:

db.books.aggregate([
  {
    $match: {
      categories: { $in: ["Programming"] }
    }
  }
]);

此查询查找所有类别中包含 "Programming" 的书籍。

我们还可以结合多种过滤技术:

db.books.aggregate([
  {
    $match: {
      $or: [{ pages: { $gt: 400 } }, { categories: { $in: ["Database"] } }]
    }
  },
  {
    $project: {
      title: 1,
      pages: 1,
      categories: 1
    }
  }
]);

这个更复杂的查询:

  • 查找页数超过 400 页或属于 "Database" 类别的书籍
  • 在输出中仅投影特定字段

示例输出:

[
  {
    _id: ObjectId("..."),
    title: "Data Science Handbook",
    pages: 600,
    categories: ["Data Science", "Programming"]
  },
  {
    _id: ObjectId("..."),
    title: "MongoDB Basics",
    pages: 250,
    categories: ["Database", "Programming"]
  }
]

总结

在本实验中,你学习了如何使用 MongoDB 的聚合管道(aggregation pipeline)来选择和转换输出字段。你首先创建了一个书籍的示例集合,然后使用 $project 阶段选择特定字段并重命名它们。你还探索了更高级的字段重命名技术,包括使用计算表达式和嵌套字段。最后,你学习了如何计算新字段、格式化输出以及过滤结果。这些技能对于在 MongoDB 中高效处理和分析数据至关重要。