Mongodb upsert仅更新选定的字段,但全部插入

时间:2012-12-28 12:55:49

标签: mongodb upsert

我试图在MongoDB中使用upsert更新文档中的单个字段(如果找到)或插入包含大量字段的整个新文档。问题是在我看来,MongoDB要么替换每个字段,要么在其upsert操作中插入一个字段子集,即它不能插入比实际想要更新的字段更多的字段。

我想做的是以下内容:

  • 我查询单个唯一值
  • 如果文档已存在,则只有时间戳值(让我们称之为'lastseen')更新为新值
  • 如果文档不存在,我将添加一长串不同的键/值对列表,这些键/值对在其生命周期的剩余时间内应保持静态。

让我们说明一下:

如果找到'name',这个例子会从我的理解更新'lastseen'日期,但如果找不到'name',它只会插入'name'+'lastseen'。

db.somecollection.update({name: "some name"},{ $set: {"lastseen": "2012-12-28"}}, {upsert:true})

如果我向第二个参数添加了更多字段(键/值对)并删除了$ set,那么每个字段都会在更新时被替换,但会对插入产生所需的效果。是否有类似$ insert或类似的东西只在插入时执行操作?

所以在我看来,我只能得到以下其中一项:

  • 正确的更新行为,但如果文档不存在,则会插入仅包含所需字段子集的文档
  • 正确的插入行为,但如果文档已存在,则会覆盖所有现有字段

我的理解是否正确?如果是这样,这可以通过一次操作来解决吗?

2 个答案:

答案 0 :(得分:31)

MongoDB 2.4有$setOnInsert

db.somecollection.update(
    {name: "some name"},
    {
        $set: {
            "lastseen": "2012-12-28"
        },
        $setOnInsert: {
            "firstseen": <TIMESTAMP>  # set on insert, not on update
        }
    },
    {upsert:true}
)

答案 1 :(得分:8)

有一个功能请求(https://jira.mongodb.org/browse/SERVER-340),已在2.3中解决。奇数版本实际上是dev版本,所以这将是2.4稳定版。

所以目前的稳定版本还没有真正做到这一点的方法。我恐怕唯一的方法是实际执行3个条件查询atm:1检查行,然后if插入或更新。

我想如果你在这里遇到锁的真正问题,你可以用单一的JS做这个功能但是这很邪恶,但它会把这个更新锁定到一个线程。

相关问题