完整替换集合中第一个匹配筛选条件的文档。注意: 这会替换整个文档(除了 _id),未在新文档中的字段将被删除。
collection(collectionName).replaceOne(filter, replacement, options)筛选条件,用于匹配要替换的文档。
{ userId: "user123" }
{ configKey: "app-settings" }替换文档,不能包含更新操作符(如 $set)。
{
userId: "user123",
name: "Alice",
age: 26,
status: "active"
}重要:
- ❌ 不能使用
$set,$inc等操作符 - ✅ 直接提供完整的新文档对象
_id字段会自动保留
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
upsert |
Boolean | false | 不存在时是否插入新文档 |
writeConcern |
Object | - | 写关注选项 |
bypassDocumentValidation |
Boolean | false | 是否绕过文档验证 |
comment |
String | - | 操作注释 |
collation |
Object | - | 排序规则 |
hint |
String/Object | - | 索引提示 |
返回 Promise<ReplaceResult>:
{
acknowledged: true,
matchedCount: 1,
modifiedCount: 1,
upsertedId: null,
upsertedCount: 0
}| 特性 | replaceOne | updateOne |
|---|---|---|
| 操作符 | ❌ 不能使用 $ | ✅ 必须使用 $ |
| 字段处理 | 删除未指定字段 | 保留未指定字段 |
| 使用场景 | 完整替换 | 部分更新 |
| _id 处理 | 保留 | 保留 |
// 原始文档
{ _id: 1, userId: "user1", name: "Alice", age: 25, status: "active", tags: ["premium"] }
// updateOne - 仅更新指定字段
await collection("users").updateOne(
{ userId: "user1" },
{ $set: { age: 26 } }
);
// 结果: { _id: 1, userId: "user1", name: "Alice", age: 26, status: "active", tags: ["premium"] }
// 其他字段保留 ✅
// replaceOne - 完整替换
await collection("users").replaceOne(
{ userId: "user1" },
{ userId: "user1", name: "Alice", age: 26 }
);
// 结果: { _id: 1, userId: "user1", name: "Alice", age: 26 }
// status 和 tags 被删除 ⚠️const result = await collection("users").replaceOne(
{ userId: "user123" },
{
userId: "user123",
name: "Alice Updated",
age: 26,
email: "alice@example.com"
}
);
console.log("Replaced:", result.modifiedCount);// 替换应用配置(常见场景)
await collection("configs").replaceOne(
{ configKey: "app-settings" },
{
configKey: "app-settings",
theme: "dark",
language: "en-US",
notifications: true,
version: 2
}
);// 如果不存在则插入
const result = await collection("settings").replaceOne(
{ settingKey: "feature-flags" },
{
settingKey: "feature-flags",
featureA: true,
featureB: false,
updatedAt: new Date()
},
{ upsert: true }
);
if (result.upsertedId) {
console.log("Inserted new document");
} else {
console.log("Replaced existing document");
}// 获取原文档的 _id
const original = await collection("users").findOne({ userId: "user123" });
// 替换时保持相同的 _id
await collection("users").replaceOne(
{ _id: original._id },
{
_id: original._id, // 明确指定 _id(可选,会自动保留)
userId: "user123",
name: "New Name",
status: "active"
}
);const customId = "custom-id-123";
await collection("documents").replaceOne(
{ _id: customId },
{
_id: customId,
title: "Document Title",
content: "Document content",
version: 2
}
);// 删除所有字段(除了 _id)
await collection("temp").replaceOne(
{ userId: "user123" },
{} // 空对象
);
// 结果: { _id: <original-id> }await collection("users").replaceOne(
{ userId: "user123" },
{
userId: "user123",
profile: {
name: "Alice",
address: {
city: "Shanghai",
country: "China"
},
preferences: {
theme: "dark",
language: "zh-CN"
}
},
tags: ["premium", "verified"]
}
);// 更新应用配置
const newConfig = {
configKey: "app-config",
version: 2,
features: {
darkMode: true,
notifications: true,
betaFeatures: false
},
limits: {
maxUsers: 1000,
maxStorage: "10GB"
},
updatedAt: new Date()
};
await collection("configs").replaceOne(
{ configKey: "app-config" },
newConfig,
{ upsert: true }
);// 保存旧版本到历史
const oldDoc = await collection("documents").findOne({ docId: "doc1" });
await collection("document_history").insertOne({
...oldDoc,
archivedAt: new Date()
});
// 替换为新版本
await collection("documents").replaceOne(
{ docId: "doc1" },
{
docId: "doc1",
content: "New content",
version: oldDoc.version + 1,
author: "Bob",
updatedAt: new Date()
}
);// 任务状态完整切换
await collection("tasks").replaceOne(
{ taskId: "task1", status: "pending" },
{
taskId: "task1",
status: "completed",
result: "success",
completedBy: "worker-1",
completedAt: new Date(),
metrics: {
duration: 120,
retries: 0
}
}
);// 清理旧数据并重建
const userId = "user123";
await collection("users").replaceOne(
{ userId },
{
userId,
name: "Fresh User",
createdAt: new Date(),
// 所有旧字段被删除,从头开始
}
);try {
await collection("users").replaceOne(
{ userId: "user123" },
{
userId: "user123",
name: "Alice"
}
);
} catch (err) {
if (err.code === "INVALID_ARGUMENT") {
// 可能原因: replacement 包含 $ 操作符
console.error("参数错误:", err.message);
} else if (err.code === "DUPLICATE_KEY") {
console.error("唯一性约束冲突:", err.message);
} else if (err.code === "WRITE_ERROR") {
console.error("写入错误:", err.message);
}
}// ❌ 错误 - replaceOne 不能使用 $ 操作符
await collection("users").replaceOne(
{ userId: "user123" },
{ $set: { name: "Alice" } }
);
// 抛出: INVALID_ARGUMENT - replacement 不能包含更新操作符
// ✅ 正确 - 提供完整文档
await collection("users").replaceOne(
{ userId: "user123" },
{ userId: "user123", name: "Alice" }
);
// 💡 如果需要部分更新,使用 updateOne
await collection("users").updateOne(
{ userId: "user123" },
{ $set: { name: "Alice" } }
);// 原文档
{ _id: 1, userId: "user1", name: "Alice", email: "alice@example.com", role: "admin" }
// ❌ 危险 - email 和 role 会丢失
await collection("users").replaceOne(
{ userId: "user1" },
{ userId: "user1", name: "Alice Updated" }
);
// 结果: { _id: 1, userId: "user1", name: "Alice Updated" }
// email 和 role 被删除 ⚠️
// ✅ 正确 - 如果要保留字段,先查询完整文档
const doc = await collection("users").findOne({ userId: "user1" });
await collection("users").replaceOne(
{ userId: "user1" },
{
...doc,
name: "Alice Updated" // 只改这个字段
}
);
// 💡 更推荐 - 使用 updateOne 进行部分更新
await collection("users").updateOne(
{ userId: "user1" },
{ $set: { name: "Alice Updated" } }
);// ✅ 推荐 - 使用索引字段
await collection("users").replaceOne(
{ userId: "user123" }, // userId 有索引
newDocument
);
// ❌ 避免 - 使用非索引字段
await collection("users").replaceOne(
{ email: "alice@example.com" }, // email 可能没有索引
newDocument
);// ❌ 不推荐 - 两次查询
const doc = await collection("users").findOne({ userId: "user123" });
await collection("users").replaceOne(
{ userId: "user123" },
{ ...doc, name: "Updated" }
);
// ✅ 推荐 - 使用 findOneAndReplace 原子操作
const oldDoc = await collection("users").findOneAndReplace(
{ userId: "user123" },
newDocument,
{ returnDocument: "before" }
);replaceOne 在成功修改文档后会自动失效相关缓存:
// 查询并缓存
await collection("configs").find({ configKey: "app-settings" }, { cache: 5000 });
// 替换文档 - 自动清理缓存
await collection("configs").replaceOne(
{ configKey: "app-settings" },
newConfig
);
// 缓存已清空- 配置管理 - 完整替换配置对象
- 文档版本 - 替换为新版本
- 状态机 - 完整状态切换
- 数据清理 - 删除旧字段并重建
- 部分更新 - 使用
updateOne代替 - 递增计数 - 使用
updateOne的$inc - 数组操作 - 使用
updateOne的$push/$pull - 保留未修改字段 - 使用
updateOne
需要更新文档?
├─ 需要保留未修改的字段?
│ ├─ 是 → 使用 updateOne + $set
│ └─ 否 → 继续
├─ 需要完整替换所有字段?
│ ├─ 是 → 使用 replaceOne
│ └─ 否 → 使用 updateOne
└─ 需要原子操作并返回文档?
├─ 部分更新 → 使用 findOneAndUpdate
└─ 完整替换 → 使用 findOneAndReplace
// ✅ 推荐 - 提供完整的文档结构
const newDocument = {
configKey: "app-settings",
version: 2,
theme: "dark",
language: "en-US",
notifications: true,
updatedAt: new Date()
};
await collection("configs").replaceOne(
{ configKey: "app-settings" },
newDocument
);/**
* @typedef {Object} UserDocument
* @property {string} userId
* @property {string} name
* @property {string} email
* @property {string} status
*/
/** @type {UserDocument} */
const newUser = {
userId: "user123",
name: "Alice",
email: "alice@example.com",
status: "active"
};
await collection("users").replaceOne({ userId: "user123" }, newUser);const result = await collection("configs").replaceOne(
{ configKey: "app-settings" },
newConfig
);
if (result.matchedCount === 0) {
console.warn("配置不存在,考虑使用 upsert: true");
} else if (result.modifiedCount === 0) {
console.log("配置内容相同,未修改");
} else {
console.log("配置已成功替换");
}updateOne()- 部分更新单个文档findOneAndReplace()- 原子地查找并替换insertOne()- 插入单个文档