MongoDB增量或Upsert
鉴于以下文件结构:MongoDB增量或Upsert,mongodb,Mongodb,鉴于以下文件结构: { '_id': ObjectId("559943fcda2485a66285576e"), 'user': '70gw3', 'data': [ { 'date': ISODate("2015-06-29T00:00:00.0Z"), 'clicks': 1, }, {
{
'_id': ObjectId("559943fcda2485a66285576e"),
'user': '70gw3',
'data': [
{
'date': ISODate("2015-06-29T00:00:00.0Z"),
'clicks': 1,
},
{
'date': ISODate("2015-06-30T00:00:00.0Z"),
'clicks': 5,
},
]
}
如何增加
2015-06-30
的点击次数
值,如果该值不存在[整个文档或特定日期],如何增加该值,使其等于1
?不幸的是,不可能在单个查询中实现您的目标。但是你可以做以下的事情
var exists = db.yourCollection.find(
{'_id': ObjectId("559943fcda2485a66285576e"), 'data.date': <your date>}
).count()
正确的答案是,虽然您需要执行两个更新操作以实现逻辑,但不需要以某种方式查找和检查数据 你有两个基本条件
var bulk=db.collection.initializeOrderedBulkOp();
//更新匹配的日期
批量查找({“用户”:“70gw3”,“数据.日期”:新日期(“2015-06-30”)})
.updateOne({“$inc”:{“数据.$.clicks”:1}});
//在日期不匹配的位置推送新元素
bulk.find({“user”:“70gw3”,“data.date”:{“$ne”:新日期(“2015-06-30”)})
.updateOne({“$push”:{“数据”:{“日期”:新日期(“2015-06-30”),“点击”:1}}});
bulk.execute();
简而言之,在为任何文档发送的两个更新请求中,只有一个操作将实际修改任何内容。这是因为测试“date”的条件是相互“反向”的,即在存在的地方“更新”,在不存在匹配元素的地方“创建”
这两种状态不可能同时存在,只要“创建”遵循“更新”逻辑,逻辑就是正确的。因此,首先尝试更新,然后尝试在没有找到匹配项的地方“创建”。你的意思是
'data':[{'date':ISODate(“2015-06-29T00:00:00.0Z”),'clicks':1},{'date':ISODate(“2015-06-30T00:00:00.0Z”),'clicks':5,}]
刚刚更新了我的问题OK,但重复的字段将被删除到日期子文档中。所以只有一个日期
,只有一个点击
。这正是我想要的,每个日期只有一次计数。请看我更新的文档。不确定我是否理解这个问题,但是是的。但是我如何指定确切的日期?我刚更新了我的问题文档结构是否正确?data
应该是一个数组吗?使用if(exists){…}else{…}
您不能保证每个日期都不会出现重复的条目。您的意思是代码中有问题或存在并发问题?好的,用修复了这个问题。看一看?
if (exists) {
db.yourCollection.update({_id: <your id>, 'data.date': <your date>}, {$inc: {'data.$.clicks': 1}})
} else {
if (db.runCommand({findAndModify: 'yourCollection', query: {_id: <your id>, 'data.date': {$ne: <your date>}}, update: {$push: {data: {date: <your date>, clicks: 1}}}}).value) {
db.yourCollection.update({_id: <your id>, 'data.date': <your date>}, {$inc: {'data.$.clicks': 1}})
}
}