繁体   English   中英

mongodb增量(如果存在),否则插入

[英]mongodb increment if exists otherwise insert

在下面的代码中,如果itemId和timestamp不存在,我想插入一个值;否则,如果我已经存在,我想增加一个值

Collection.update({
                itemId: itemId,
                timestamp: moment.unix(timestamp).set('seconds', 0).toDate(),
            },
            {
                '$inc': {
                    'data.ph1': data.ph1,
                    'data.ph2': data.ph2,
                    'data.ph3': data.ph3,
                    'data.total': data.total
                },
            },
            { upsert: true },
            (err,resp) => {
                if(err) {
                    reject(err);
                } else {  
                    resolve('minute value incremented' + gatewayId );
                }
            });

最终将创建多个文档。 先感谢您。

您仍然具有毫秒部分(或者至少会以这种方式出现),因此只要该部分在当前分钟内是唯一的,这仍将插入新文档。

这是您的代码,错误地将毫秒保留在原处:

 var timestamp = ( Date.now() / 1000 ); console.log(new Date()); console.log(timestamp); console.log(moment.unix(timestamp).set("seconds",0).toDate()); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.1/moment.min.js"></script> 

并且当您删除毫秒时也是正确的:

 var timestamp = ( Date.now() / 1000 ); console.log(new Date()); console.log(timestamp); console.log(moment.unix(timestamp).set("seconds",0).set("milliseconds",0).toDate()); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.1/moment.min.js"></script> 

或者在传递timestamp值之前将其四舍五入:

 var timestamp = ( Date.now() / 1000 ) console.log(new Date()); timestamp = timestamp - ( timestamp % 60 ); console.log(timestamp); console.log(moment.unix(timestamp).toDate()); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.1/moment.min.js"></script> 

因此,当日期实际上如您所愿地四舍五入到“分钟”时,就可以了。

底线是,仅当提供的条件(实际上是文档的“键”)与任何现有文档不匹配时,才会出现“ upsert”,因此每个请求中都有明显的不同,最有可能的候选者是代码中的timestamp值及其后续转换。

也就是说,除非您实际上是从外部或已定义的源中读取timestamp ,否则获取“当前时间”的最佳方法是简单地使用vanilla Date方法:

 var timestamp = Date.now(); timestamp = timestamp - ( timestamp % ( 1000 * 60 ) ); console.log(new Date(timestamp)); 

这应该可以完成工作,而无需弄乱其他导入的库。

因此,您确实应该查看为什么拥有当前代码,并且如果要读取已经定义的值,则实际上“确保”舍入毫秒和秒,因为取模方法通常效果最好。

时间戳本身之外的唯一其他原因是每个请求中更改的实际itemId值。 但是,如果执行此操作,则可以预期该操作,并且该操作当然会创建一个不存在“组合”的新文档,因为这是要执行的操作。

编辑 :实际上,您不需要唯一的索引来使ups正常工作,但是当您进行很多upsert和/或集合很大时,仍然建议使用它。

编辑 :正如Neil Yunn所指出的那样,您已经将时间戳的秒部分设置为零,但是忘记了使用毫秒部分进行的操作。

您应该在upsert中提供一个唯一的字段,以便MongoDB有机会找到一个可能存在的记录。 您的字段itemIdtimestamp应该在集合中标记为唯一索引。

在Mongo Shell中输入

db.items.createIndex({"itemId": 1, "timestamp": 1}, {"unique": true})

用您收藏的实际名称替换items

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM