Mongodb upsert only update selected fields, but insert all

心不动则不痛 提交于 2019-11-29 12:37:35

问题


I am trying to use upsert in MongoDB to update a single field in a document if found OR insert a whole new document with lots of fields. The problem is that it appears to me that MongoDB either replaces every field or inserts a subset of fields in its upsert operation, i.e. it can not insert more fields than it actually wants to update.

What I want to do is the following:

  • I query for a single unique value
  • If a document already exists, only a timestamp value (lets call it 'lastseen') is updated to a new value
  • If a document does not exists, I will add it with a long list of different key/value pairs that should remain static for the remainder of its lifespan.

Lets illustrate:

This example would from my understanding update the 'lastseen' date if 'name' is found, but if 'name' is not found it would only insert 'name' + 'lastseen'.

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

If I added more fields (key/value pairs) to the second argument and drop the $set, then every field would be replaced on update, but would have the desired effect on insert. Is there anything like $insert or similar to perform operations only when inserting?

So it seems to me that I can only get one of the following:

  • The correct update behavior, but would insert a document with only a subset of the desired fields if document does not exist
  • The correct insert behavior, but would then overwrite all existing fields if document already exists

Are my understanding correct? If so, is this possible to solve with a single operation?


回答1:


MongoDB 2.4 has $setOnInsert

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



回答2:


There is a feature request for this ( https://jira.mongodb.org/browse/SERVER-340 ) which is resolved in 2.3. Odd releases are actually dev releases so this will be in the 2.4 stable.

So there is no real way in the current stable versions to do this yet. I am afraid the only method is to actually do 3 conditional queries atm: 1 to check the row, then a if to either insert or update.

I suppose if you had real problems with lock here you could do this function with sole JS but that's evil however it would lock this update to a single thread.



来源:https://stackoverflow.com/questions/14069897/mongodb-upsert-only-update-selected-fields-but-insert-all

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!