mongodb 不存在就插入
一
不存在插入,存在不做任何处理。
db.companies.updateOne(
{"company": "test"},
{ $setOnInsert: { "name": "nameVal2", ... } },
{ upsert: true }
)
{"company": "test"}是匹配条件
{ $setOnInsert: { "name": "nameVal2", ... } } 查询不到就会插入这里设定的值
{ upsert: true } 开启upsert
如果是项不存在插入,存在更新,请查看findandmodify/findoneandupdate
二
进一步提要求,每间隔60秒/1分钟插入一条数据。
比如有很多重复的数据(日志,告警)等,相同的内容不想重复插入,设定间隔,比如1小时等再插入新的,如何做呢?
还是使用updateOne,过滤条件就是,查找最新的时间(也就是最大的时间),方法就是按照时间倒序排序,查找第一条记录,也就是最后插入的一条记录,然后判断是否在时间间隔内,如果在,则不做任何操作(updateone原本设定的是更新,我们不给定更新内容,则不做任何操作),如果不在时间间隔内,则说明超过时间间隔了,插入。举例如下:
db.getCollection("xxx").updateOne(
{ts: {$gt: new Date(ISODate().getTime() - 60000)}},
{$setOnInsert: {"level": 3, "type": "bbb", "ts": new Date()}},
{
upsert: true,
$sort: {ts: -1},
$limit: 1
}
)
{ts: {$gt: new Date(ISODate().getTime() - 60000)}} 判断ts字段(ISODate类型)是否大于当前时间减去60秒,也就是还在时间间隔内
{$setOnInsert: {"level": 3, "type": "bbb", "ts": new Date()}} 设定不满足条件时的插入内容
upsert: true 开启更新插入
$sort: {ts: -1} ts倒序插叙
$limit: 1 只获取第一条数据
三
虽然上面语句可以实现,但是有一个问题,在官方api中,我没有找到设定limit的选项,直接调用mongo的语句可以实现,但是使用api,比如c-driver的mongoc_collection_update_one时,会报错。因为option参数中没有limit。
最后测试了很多,也没有找到如何实现,现在只能先查找过滤,再根据查找结果判断是否写入。
https://www.mongodb.com/docs/v7.0/reference/method/db.collection.updateOne/#mongodb-method-db.collection.updateOne
https://stackoverflow.com/questions/48220677/mongodb-how-to-insert-only-if-does-not-exists-no-update-if-exist
https://stackoverflow.com/questions/30996728/adding-subtracting-days-to-isodate-in-mongodb-shell