mongodb中的数据是这样的
{
"_id": "1",
"a": 1,
"b": 2,
"c": 3
"d": 4
}
我可以使用单个“$set”运算符更新文档。
db.collection.update({"_id": "1"}, {
"$set": {
"a": 100,
"b": 200,
"c": 300,
"d": 400
}
})
我还可以使用多个“$set”更新文档(每个字段都有一个“$set”)。
db.collection.update({"_id": "1"}, [
{
"$set": { "a": 100 }
},
{
"$set": { "b": 200 }
},
{
"$set": { "c": 300 }
},
{
"$set": { "d": 400 }
}
])
我想知道使用“多集”版本对mongodb端是否有任何性能问题。如果在某些情况下我需要的话,可以使用“多集”版本吗?
对于您的情况,我认为性能差异即使不是没有,也会微不足道。他们的
explain
计划几乎相同。
explain
单个$set
输出:
{
"$clusterTime": {
"clusterTime": Timestamp(1734276869, 3),
"signature": {
"hash": BinData(0, "tRv1PQVgmouDxOtttOdSk2z0O1U="),
"keyId": NumberLong(7394893876424605697)
}
},
"command": {
"$db": "75f38391413d12711811639fd9b97e4f",
"filter": {},
"find": "collection",
"maxTimeMS": NumberLong(20000)
},
"executionStats": {
"allPlansExecution": [],
"executionStages": {
"advanced": 1,
"direction": "forward",
"docsExamined": 1,
"executionTimeMillisEstimate": 0,
"isEOF": 1,
"nReturned": 1,
"needTime": 0,
"needYield": 0,
"restoreState": 0,
"saveState": 0,
"stage": "COLLSCAN",
"works": 2
},
"executionSuccess": true,
"executionTimeMillis": 0,
"nReturned": 1,
"totalDocsExamined": 1,
"totalKeysExamined": 0
},
"explainVersion": "1",
"operationTime": Timestamp(1734276869, 3),
"queryPlanner": {
"indexFilterSet": false,
"maxIndexedAndSolutionsReached": false,
"maxIndexedOrSolutionsReached": false,
"maxScansToExplodeReached": false,
"namespace": "75f38391413d12711811639fd9b97e4f.collection",
"parsedQuery": {},
"planCacheKey": "5F5FC979",
"queryHash": "5F5FC979",
"rejectedPlans": [],
"winningPlan": {
"direction": "forward",
"stage": "COLLSCAN"
}
},
"serverParameters": {
"internalDocumentSourceGroupMaxMemoryBytes": 104857600,
"internalDocumentSourceSetWindowFieldsMaxMemoryBytes": 104857600,
"internalLookupStageIntermediateDocumentMaxSizeBytes": 104857600,
"internalQueryFacetBufferSizeBytes": 104857600,
"internalQueryFacetMaxOutputDocSizeBytes": 104857600,
"internalQueryMaxAddToSetBytes": 104857600,
"internalQueryMaxBlockingSortMemoryUsageBytes": 104857600,
"internalQueryProhibitBlockingMergeOnMongoS": 0
}
}
explain
多个$set
输出:
{
"$clusterTime": {
"clusterTime": Timestamp(1734276224, 3),
"signature": {
"hash": BinData(0, "QUsSlU1zBAvtbFAgbv3/fA7RENU="),
"keyId": NumberLong(7394893876424605697)
}
},
"command": {
"$db": "3d58f286ab6b7455181163098d794665",
"filter": {},
"find": "collection",
"maxTimeMS": NumberLong(20000)
},
"executionStats": {
"allPlansExecution": [],
"executionStages": {
"advanced": 1,
"direction": "forward",
"docsExamined": 1,
"executionTimeMillisEstimate": 0,
"isEOF": 1,
"nReturned": 1,
"needTime": 0,
"needYield": 0,
"restoreState": 0,
"saveState": 0,
"stage": "COLLSCAN",
"works": 2
},
"executionSuccess": true,
"executionTimeMillis": 0,
"nReturned": 1,
"totalDocsExamined": 1,
"totalKeysExamined": 0
},
"explainVersion": "1",
"operationTime": Timestamp(1734276224, 3),
"queryPlanner": {
"indexFilterSet": false,
"maxIndexedAndSolutionsReached": false,
"maxIndexedOrSolutionsReached": false,
"maxScansToExplodeReached": false,
"namespace": "3d58f286ab6b7455181163098d794665.collection",
"parsedQuery": {},
"planCacheKey": "5F5FC979",
"queryHash": "5F5FC979",
"rejectedPlans": [],
"winningPlan": {
"direction": "forward",
"stage": "COLLSCAN"
}
},
"serverParameters": {
"internalDocumentSourceGroupMaxMemoryBytes": 104857600,
"internalDocumentSourceSetWindowFieldsMaxMemoryBytes": 104857600,
"internalLookupStageIntermediateDocumentMaxSizeBytes": 104857600,
"internalQueryFacetBufferSizeBytes": 104857600,
"internalQueryFacetMaxOutputDocSizeBytes": 104857600,
"internalQueryMaxAddToSetBytes": 104857600,
"internalQueryMaxBlockingSortMemoryUsageBytes": 104857600,
"internalQueryProhibitBlockingMergeOnMongoS": 0
}
}
考虑到示例中仅更新 1 个文档的查询模式,并且您通过
_id
获取,我认为不会有任何可观察到的性能差异。
除了性能之外,还有 2 个注意事项:
$set
操作,则需要将它们分成不同的阶段例如你
$set
a 为 c * d = 12,b 为 a + 1 = 12 + 1 = 13。你需要做:
db.collection.update({
"_id": "1"
},
[
{
"$set": {
"a": {
"$multiply": [
"$c",
"$d"
]
}
}
},
{
"$set": {
"b": {
"$add": [
"$a",
1
]
}
}
}
])
单个
$set
不会给你预期的结果 b = 13,而是 2,因为 a 尚未被评估为 12(保留 1 作为值)
db.collection.update({
"_id": "1"
},
[
{
"$set": {
"a": {
"$multiply": [
"$c",
"$d"
]
},
"b": {
"$add": [
"$a",
1
]
}
}
}
])
$set
语句更具可读性或易于管理。但我承认这是相当主观的,你可以反过来考虑。