MongoDB Aggregation Pipeline 是 MongoDB 数据库中强大的数据处理工具,有着灵活的处理能力和强大的聚合功能。然而,在实践中,我们很容易犯以下五个错误。这篇文章将引导你解决这些错误并完成聚合查询。
1. $group 中引用不存在的字段
在 $group 阶段聚合数据时,要确保引用的列在先前的阶段中已经存在。如果不是,将会抛出异常。在下面的例子中,假设我们的文档只有 name 字段,而我们在 $group 中引用了 age 字段:
db.collection.aggregate([ {$group: {_id: "$name", total_age: {$sum: "$age"}}} ]);
在这种情况下,将会抛出以下异常:
Error: nonexistent field 'age'
要避免该错误,必须在 $group 前确保包含 age 字段的阶段已经执行。例如,在上例中,如果先在 pipeline 中加入 $addFields,添加 age 字段:
db.collection.aggregate([ {$addFields: {age: {$subtract: [2019, "$birth_year"]}}}, {$group: {_id: "$name", total_age: {$sum: "$age"}}} ]);
2. $group 中字段名与 _id 冲突
在 $group 阶段聚合数据时,要注意避免聚合字段名与 _id 冲突的情况。如果发生冲突,聚合结果可能会出现意外行为。
例如,在以下示例中,假设我们的文档有 name 和 age 两个字段,我们要按照 name 分组并计算每个组中的文档数量。如果我们在 $group 中指定同名的字段,将导致意外结果。
db.collection.aggregate([ {$group: {_id: "$name", name: {$sum: 1}}} ]);
在这种情况下,将会出现异常:
Error: field 'name' is not unique in this object
为了避免这个错误,最好使用不同的名称来区分聚合字段和 _id 字段:
db.collection.aggregate([ {$group: {_id: "$name", count: {$sum: 1}}} ]);
3. $project 中引用不存在的字段
在 $project 阶段,要注意仅仅引用已经定义的字段,否则将会抛出异常。例如,在以下示例中,如果在 $project 列表中引用了未在上一个阶段中引入的字段,将会出现异常:
db.collection.aggregate([ {$match: {age: {$gte: 18}}}, {$project: {name: 1, age: 1, gender: "$info.gender"}} ]);
如果文档没有 initial 字段,则将导致以下异常:
Error: nonexistent field 'info'
为了避免这个错误,最好先引用包含需要的字段的阶段,如下所示:
db.collection.aggregate([ {$match: {age: {$gte: 18}}}, {$project: {name: 1, age: 1, info: 1}}, {$project: {name: 1, age: 1, gender: "$info.gender"}} ]);
4. $sort 中使用未定义的字段
在 $sort 阶段,要确保引用的字段已经定义。如果没有定义,将会抛出异常。
例如,在以下示例中,假设我们有一个 name 字段,但是在 $sort 阶段中编写了错误的字段名:
db.collection.aggregate([ {$sort: {invalid_field: 1}}, {$group: {_id: "$name"}} ]);
这将导致以下异常:
Error: sort key not found: invalid_field
为了避免这个错误,最好先在 pipeline 中定义需要用到的字段:
db.collection.aggregate([ {$project: {name: 1}}, {$sort: {name: 1}}, {$group: {_id: "$name"}} ]);
5. $lookup 中引用不存在的集合
在 $lookup 阶段,要确保引用的集合是存在的。如果不存在,将会抛出异常。例如,在以下示例中,假设我们想使用 $lookup 引用名为 users 的不存在的集合。
db.collection.aggregate([ {$lookup: { from: "users", localField: "userId", foreignField: "_id", as: "user" }} ])
这将导致以下异常:
Error: $lookup: from: users: Collection not found
为了避免这个错误,最好确保引用的集合存在,或者在 pipeline 中先创建要使用的集合。
结论
在使用 MongoDB Aggregation Pipeline 进行查询时,确保避免这五种错误,可以让我们避免意外行为和异常。总结一下:
- 确保在聚合前定义了要用到的字段。
- 避免聚合字段名与 _id 字段冲突。
- 在 $project 阶段中仅引用已经定义的字段。
- 在 $sort 阶段中确保字段已经定义。
- 保证 $lookup 引用的集合存在或者先在 pipeline 中创建。
希望这篇文章能够帮助你在使用 MongoDB Aggregation Pipeline 进行编程时,避免这五个常见错误,让你更加高效地进行数据处理。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64b09ff348841e9894cb43b5