mongodb增量,否则插入

时间:2018-05-02 13:55:05

标签: javascript mongodb mongodb-query upsert

在下面的代码中,我想插入一个值,如果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 );
                }
            });

最终会创建多个文档。提前谢谢。

2 个答案:

答案 0 :(得分:1)

你仍然有毫秒部分(或者至少它会出现这种情况),所以只要该部分在当前分钟内是唯一的,这仍然会插入一个新文档。

这是你的代码错误地留下毫秒的时间:

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”,因此每个请求中的某些内容明显不同且最有可能candidate是代码中的timestamp值,后续转换。

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

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

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

所以你真的应该看看为什么你有你当前的代码,如果你正在读取已经定义的值,那么实际上“确保”在舍入中删除毫秒和秒,因为模数方法通常做得最好。

时间戳本身之外的唯一其他原因是每个请求中更改的实际itemId值。但是,如果你这样做,那么行动是预期的,当然会创建一个新的文档,其中“组合”不存在,因为这是它的意图。

答案 1 :(得分:0)

编辑:您实际上并不需要上传的唯一索引,但是当您进行大量的upsert和/或收集时,它仍然是推荐的挺大。

编辑:正如Neil Yunn指出的那样,你已经将时间戳的秒部分设置为零,但忘记用毫秒部分做同样的事情。

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

在Mongo shell类型

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

items替换为您的收藏品的实际名称。