在MongoDB中,使用 $project 阶段可以重塑每个文档的结构,类似于SQL中的 SELECT 子句。你可以使用 $project 来包括或排除字段、创建新的字段、重命名字段,甚至执行一些简单的运算。
使用 $project 阶段的基本结构
javascript
{
$project: {
<field1>: <expression1>,
<field2>: <expression2>,
// 其他字段
}
}
<field>是你想要包含在输出文档中的字段名称。<expression>是一个包括或排除字段的布尔值、算术操作、字符串操作、日期操作等。
代码示例
以下是使用Node.js进行投影操作的详细示例。首先确保安装了MongoDB的Node.js驱动:
bash
npm install mongodb
插入示例数据
javascript
const { MongoClient } = require('mongodb');
async function insertData() {
const uri = "mongodb://localhost:27017";
const client = new MongoClient(uri, { useUnifiedTopology: true });
try {
await client.connect();
const db = client.db('myDatabase');
const collection = db.collection('orders');
await collection.deleteMany({}); // 清空集合
await collection.insertMany([
{ customerId: 1, amount: 100, status: "shipped", date: new Date("2021-01-01") },
{ customerId: 1, amount: 200, status: "pending", date: new Date("2021-02-01") },
{ customerId: 2, amount: 150, status: "shipped", date: new Date("2021-03-01") },
{ customerId: 2, amount: 50, status: "pending", date: new Date("2021-04-01") },
{ customerId: 3, amount: 250, status: "shipped", date: new Date("2021-05-01") }
]);
console.log("Data inserted");
} finally {
await client.close();
}
}
insertData().catch(console.error);
使用 $project 进行投影
javascript
async function aggregateData() {
const uri = "mongodb://localhost:27017";
const client = new MongoClient(uri, { useUnifiedTopology: true });
try {
await client.connect();
const db = client.db('myDatabase');
const collection = db.collection('orders');
// 使用 $project 选择特定字段
console.log("\n$project stage (select specific fields):");
let result = await collection.aggregate([
{
$project: {
_id: 0, // 不包括 _id 字段
customerId: 1, // 包括 customerId 字段
amount: 1, // 包括 amount 字段
status: 1 // 包括 status 字段
}
}
]).toArray();
console.log(result);
// 使用 $project 创建新的字段
console.log("\n$project stage (create new fields):");
result = await collection.aggregate([
{
$project: {
customerId: 1,
amount: 1,
status: 1,
amountWithTax: { $multiply: ["$amount", 1.1] } // 创建新的字段 amountWithTax,值为 amount 的 1.1 倍
}
}
]).toArray();
console.log(result);
// 使用 $project 重命名字段
console.log("\n$project stage (rename fields):");
result = await collection.aggregate([
{
$project: {
_id: 0,
customer: "$customerId", // 将 customerId 字段重命名为 customer
total: "$amount", // 将 amount 字段重命名为 total
status: 1,
date: 1
}
}
]).toArray();
console.log(result);
// 使用 $project 包含计算字段
console.log("\n$project stage (include calculated fields):");
result = await collection.aggregate([
{
$project: {
customerId: 1,
amount: 1,
status: 1,
year: { $year: "$date" }, // 包括 year 字段,值为 date 字段的年份
month: { $month: "$date" } // 包括 month 字段,值为 date 字段的月份
}
}
]).toArray();
console.log(result);
} finally {
await client.close();
}
}
aggregateData().catch(console.error);
在这个示例中,我们演示了如何使用 $project 阶段进行投影操作:
- 选择特定字段。
- 创建新的字段。
- 重命名字段。
- 包含计算字段。
运行这个脚本后,你会得到如下结果(示例输出):
javascript
// select specific fields 结果
$project stage (select specific fields):
[
{ customerId: 1, amount: 100, status: 'shipped' },
{ customerId: 1, amount: 200, status: 'pending' },
{ customerId: 2, amount: 150, status: 'shipped' },
{ customerId: 2, amount: 50, status: 'pending' },
{ customerId: 3, amount: 250, status: 'shipped' }
]
// create new fields 结果
$project stage (create new fields):
[
{ customerId: 1, amount: 100, status: 'shipped', amountWithTax: 110 },
{ customerId: 1, amount: 200, status: 'pending', amountWithTax: 220 },
{ customerId: 2, amount: 150, status: 'shipped', amountWithTax: 165 },
{ customerId: 2, amount: 50, status: 'pending', amountWithTax: 55 },
{ customerId: 3, amount: 250, status: 'shipped', amountWithTax: 275 }
]
// rename fields 结果
$project stage (rename fields):
[
{ customer: 1, total: 100, status: 'shipped', date: 2021-01-01T00:00:00.000Z },
{ customer: 1, total: 200, status: 'pending', date: 2021-02-01T00:00:00.000Z },
{ customer: 2, total: 150, status: 'shipped', date: 2021-03-01T00:00:00.000Z },
{ customer: 2, total: 50, status: 'pending', date: 2021-04-01T00:00:00.000Z },
{ customer: 3, total: 250, status: 'shipped', date: 2021-05-01T00:00:00.000Z }
]
// include calculated fields 结果
$project stage (include calculated fields):
[
{ customerId: 1, amount: 100, status: 'shipped', year: 2021, month: 1 },
{ customerId: 1, amount: 200, status: 'pending', year: 2021, month: 2 },
{ customerId: 2, amount: 150, status: 'shipped', year: 2021, month: 3 },
{ customerId: 2, amount: 50, status: 'pending', year: 2021, month: 4 },
{ customerId: 3, amount: 250, status: 'shipped', year: 2021, month: 5 }
]
其他语言示例
类似的投影操作也可以在其他编程语言中实现,如Python。以下是Python的示例代码:
安装PyMongo
在终端中运行以下命令来安装PyMongo:
bash
pip install pymongo
使用Python进行投影
python
from pymongo import MongoClient
def main():
client = MongoClient('mongodb://localhost:27017/')
db = client['myDatabase']
collection = db['orders']
# 使用 $project 选择特定字段
print("\n$project stage (select specific fields):")
pipeline = [
{
'$project': {
'_id': 0, # 不包括 _id 字段
'customerId': 1, # 包括 customerId 字段
'amount': 1, # 包括 amount 字段
'status': 1 # 包括 status 字段
}
}
]
result = list(collection.aggregate(pipeline))
for doc in result:
print(doc)
# 使用 $project 创建新的字段
print("\n$project stage (create new fields):")
pipeline = [
{
'$project': {
'customerId': 1,
'amount': 1,
'status': 1,
'amountWithTax': { '$multiply': ["$amount", 1.1] } # 创建新的字段 amountWith