Possible to do partial update, but complete document upsert in mongodb?

寵の児 提交于 2019-12-14 03:04:30

问题


Using mongoDB, I want to update a specific field conditionally (update field if existing value is less than update). However, if the document doesn't exist, I want the whole document to be inserted.

What previously worked:

I have previously used a combination of $max (to set the field) and $setOnInsert (to set the rest of the document), which did what i wanted.

This prevented future updates from decrementing the given field. For example, having the following document schema:

{
  _id: [ObjectId]
  key: [string],
  foo: [string],
  bar: [string],
  value: [number]
}

My updates looked something like this:

db.collection.update(
  { key: "something unique" },
  {
    $max : { value: 100 },
    $setOnInsert: {
      key: "something unique",
      foo: "yes",
      bar: "probably"
    }
  },
  { upsert: true }
)

The first update would create the document with a given value and all subsequent updates would never decrement the value field or change any other data.

To do this programmatically, I had to remove the _id and value fields from the document, to be able to use it as $setOnInsert. Which was tolerable.

Change to schema:

Now - I wanted to move some fields, including value, into an embedded document. So my document schema now looks like this:

{
  key: [string],
  data: {
    foo: [string],
    bar: [string],
    value: [number]
  }
}

Attempting to use a similar idea for an update, i attempt this:

db.collection.update(
  { key: "something unique" },
  {
    $max : { "data.value": 100 },
    $setOnInsert: {
      key: "something unique",
      data: {
        foo: "yes",
        bar: "probably"
      }
    }
  },
  { upsert: true }
)

But this fails with the following MongoError: Updating the path 'data' would create a conflict at 'data'.

Works, but not easily constructed:

I could make it work using dot-notation:

db.collection.update(
  { key: "something unique" },
  {
    $max : { "data.value": 100 },
    $setOnInsert: {
      key: "something unique",
      "data.foo": "yes",
      "data.bar": "probably"
      }
  },
  { upsert: true }
)

But constructing this update programmatically would be somewhat of a mess, I think. Some C# examples are welcome though :)

What is the most clean and efficient way I can achieve this concept of conditionally updating a single field, but at the same time insert the complete document if it doesn't exist already?

Other approaches than what I am attempting are welcome.

来源:https://stackoverflow.com/questions/56006804/possible-to-do-partial-update-but-complete-document-upsert-in-mongodb

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