本文演示如何在 MongoDB 中使用 ObjectId 配合 findOne() 精确查询单个文档,这是按主键查找的标准方式。
创建示例数据
> db.findOneWorkingDemo.insertOne({"ClientId":1,"ClientName":"Larry","ClientAge":26});
{ "acknowledged" : true, "insertedId" : ObjectId("5cd7c1716d78f205348bc64d") }
> db.findOneWorkingDemo.insertOne({"ClientId":2,"ClientName":"Chris","ClientAge":28});
{ "acknowledged" : true, "insertedId" : ObjectId("5cd7c17d6d78f205348bc64e") }
> db.findOneWorkingDemo.insertOne({"ClientId":3,"ClientName":"Robert","ClientAge":34});
{ "acknowledged" : true, "insertedId" : ObjectId("5cd7c1896d78f205348bc64f") }
显示所有数据
> db.findOneWorkingDemo.find().pretty();
{ "_id" : ObjectId("5cd7c1716d78f205348bc64d"), "ClientId" : 1, "ClientName" : "Larry", "ClientAge" : 26 }
{ "_id" : ObjectId("5cd7c17d6d78f205348bc64e"), "ClientId" : 2, "ClientName" : "Chris", "ClientAge" : 28 }
{ "_id" : ObjectId("5cd7c1896d78f205348bc64f"), "ClientId" : 3, "ClientName" : "Robert", "ClientAge" : 34 }
使用 findOne() 配合 ObjectId 查询特定文档
> db.findOneWorkingDemo.findOne({ "_id": ObjectId("5cd7c17d6d78f205348bc64e") });
结果
{ "_id" : ObjectId("5cd7c17d6d78f205348bc64e"), "ClientId" : 2, "ClientName" : "Chris", "ClientAge" : 28 }
findOne() vs find() 对比
| 特性 | findOne() | find() |
|---|---|---|
| 返回类型 | 单个 Document (Object) 或 null | Cursor (可迭代) |
| 查询结束 | 找到第一个即停止 | 需手动迭代或 toArray() |
| 性能 | 略快 (内部 limit: 1) | 标准 |
| 适用场景 | 按 _id 或唯一键查询 | 多文档、需分页/处理 |
| Projection 支持 | 支持 | 支持 |
常用查询模式
// 1. 仅按 _id 查询 (最常用,走 _id 索引)
db.collection.findOne({ _id: ObjectId("...") });
// 2. 按 _id 查询 + 只返回特定字段
db.collection.findOne(
{ _id: ObjectId("...") },
{ projection: { name: 1, email: 1, _id: 0 } }
);
// 3. 按业务唯一键查询
db.users.findOne({ email: "user@example.com" });
db.products.findOne({ sku: "PROD-001" });
// 4. 在应用代码中 (Node.js 示例)
const doc = await db.collection('users').findOne({ _id: new ObjectId(idString) });
ObjectId 字符串转换
// Shell 中
ObjectId("5cd7c17d6d78f205348bc64e")
// Node.js Driver
const { ObjectId } = require('mongodb');
new ObjectId("5cd7c17d6d78f205348bc64e")
// Python (PyMongo)
from bson.objectid import ObjectId
ObjectId("5cd7c17d6d78f205348bc64e")
性能提示
_id自动拥有唯一索引,按 _id 查询极快 (O(1) B-Tree 查找)- 避免在高频查询中使用
find().limit(1)代替findOne() - 如果只需某几个字段,务必使用 Projection 减少网络传输