MongoDB - 更新一个或另一个字段
MongoDB - Update One Field or Another
我对 MongoDB 很陌生,所以这可能是我对它的经验不足。我正在尝试做一个 upsert
,当找到记录时,它将根据多个条件更新多个字段。
我在 collection 中有以下记录:
{
modelId: "5e68c7eaa0887971ea6ef54c",
versionId: 999,
timeStamp: "1/1/2020",
oldValue: 'Blue',
newValue: 'Red'
}
我正在尝试使用单个 upsert
语句来满足以下条件,以避免多次访问数据库(基于匹配 modelId
和 [ 的文档的查询=17=] 找到:
- 如果
timeStamp
的新记录在 (lt
) 现有文档之前,则更新 oldValue
- 如果
timeStamp
的新记录在 (gt
) 现有文档之后,则更新 newValue
- 如果找不到匹配的记录,则插入新记录。
在伪代码术语中,我试图用 upsert
语句来做到这一点:
existingRecord = item in collection matching modelId and versionId
if(existingRecord = null)
{
//insert newRecord
}
if(newRecord.timeStamp < existingRecord.timeStamp)
{
existingRecord.oldValue = newRecord.oldValue
existingRecord.timeStamp = newRecord.timeStamp
}
else if(newRecord.timeStamp > existingRecord.timeStamp)
{
existingRecord.newValue = newRecord.newValue
existingRecord.timeStamp = newRecord.timeStamp
}
我看到了根据日期条件进行 upsert
的可能性,例如:
db.collection.update( { id:o.id, date: { $lt:o.date } }, {$set : { o }}, {upsert:true} );
我不知道如何扩展它以便能够根据 timeStamp
值更新 oldValue
或 newValue
。
我计划每天将大量记录插入 collection,估计大约 1MM,我不想做一个 find()
然后一个 update()
每条记录。
我正在使用 Mongo 4.0,如有任何建议,我将不胜感激。
谢谢!
嗯,在4.0 版 中,您不能在更新查询中使用条件。因此,您最终会触发两个查询。
db.collection.update({condition}, { $set: { o } }, { multi: true ,upsert:true });
db.collection.update({!condition}, { $set: { n } }, { multi: true ,upsert:true });
但是,在版本 4.2 中,添加了 db.collection.update 管道,其中允许聚合。
而且,它只包含以下聚合阶段:
$addFields and its alias $set
$project and its alias $unset
$replaceRoot and its alias $replaceWith.
希望这会有所帮助:)
更新
我添加了 $set
阶段来更新文档。如果时间戳条件为真,它将更新,否则它不会更新。并适用于其他条件。
我已经使用了时间戳的长值,你可以根据你的情况使用。
db.collection.update(
{
modelId: "5e68c7eaa0887971ea6ef54c",
versionId: 999,
},
[
{
$set:{
"oldValue":{
$cond:[
{
$lt:[
"timestamp",
1598598257000
]
},
"green",
"$oldValue"
]
}
}
},
{
$set:{
"newValue":{
$cond:[
{
$gt:[
"timestamp",
1518598257000
]
},
"pink",
"$newValue"
]
}
}
}
]
)
我对 MongoDB 很陌生,所以这可能是我对它的经验不足。我正在尝试做一个 upsert
,当找到记录时,它将根据多个条件更新多个字段。
我在 collection 中有以下记录:
{
modelId: "5e68c7eaa0887971ea6ef54c",
versionId: 999,
timeStamp: "1/1/2020",
oldValue: 'Blue',
newValue: 'Red'
}
我正在尝试使用单个 upsert
语句来满足以下条件,以避免多次访问数据库(基于匹配 modelId
和 [ 的文档的查询=17=] 找到:
- 如果
timeStamp
的新记录在 (lt
) 现有文档之前,则更新oldValue
- 如果
timeStamp
的新记录在 (gt
) 现有文档之后,则更新newValue
- 如果找不到匹配的记录,则插入新记录。
在伪代码术语中,我试图用 upsert
语句来做到这一点:
existingRecord = item in collection matching modelId and versionId
if(existingRecord = null)
{
//insert newRecord
}
if(newRecord.timeStamp < existingRecord.timeStamp)
{
existingRecord.oldValue = newRecord.oldValue
existingRecord.timeStamp = newRecord.timeStamp
}
else if(newRecord.timeStamp > existingRecord.timeStamp)
{
existingRecord.newValue = newRecord.newValue
existingRecord.timeStamp = newRecord.timeStamp
}
我看到了根据日期条件进行 upsert
的可能性,例如:
db.collection.update( { id:o.id, date: { $lt:o.date } }, {$set : { o }}, {upsert:true} );
我不知道如何扩展它以便能够根据 timeStamp
值更新 oldValue
或 newValue
。
我计划每天将大量记录插入 collection,估计大约 1MM,我不想做一个 find()
然后一个 update()
每条记录。
我正在使用 Mongo 4.0,如有任何建议,我将不胜感激。
谢谢!
嗯,在4.0 版 中,您不能在更新查询中使用条件。因此,您最终会触发两个查询。
db.collection.update({condition}, { $set: { o } }, { multi: true ,upsert:true });
db.collection.update({!condition}, { $set: { n } }, { multi: true ,upsert:true });
但是,在版本 4.2 中,添加了 db.collection.update 管道,其中允许聚合。
而且,它只包含以下聚合阶段:
$addFields and its alias $set
$project and its alias $unset
$replaceRoot and its alias $replaceWith.
希望这会有所帮助:)
更新
我添加了 $set
阶段来更新文档。如果时间戳条件为真,它将更新,否则它不会更新。并适用于其他条件。
我已经使用了时间戳的长值,你可以根据你的情况使用。
db.collection.update(
{
modelId: "5e68c7eaa0887971ea6ef54c",
versionId: 999,
},
[
{
$set:{
"oldValue":{
$cond:[
{
$lt:[
"timestamp",
1598598257000
]
},
"green",
"$oldValue"
]
}
}
},
{
$set:{
"newValue":{
$cond:[
{
$gt:[
"timestamp",
1518598257000
]
},
"pink",
"$newValue"
]
}
}
}
]
)