使用$ min在数组位置上插值

时间:2017-06-19 12:17:35

标签: arrays mongodb mongodb-query

我想插入一个带有默认值的新文档作为数组的一部分,或者如果文档已经存在则更新数组的那部分。

我的想法是:

db.test.update(
    { "a": 5 },
    { $setOnInsert: { "b": [0, 0] }, $min: { "b.0": 5 } },
    { upsert: true }
);

如果我这样做,那么我得到:

  

无法同时更新'b'和'b.0'

另一个想法是删除$setOnInsert并保留$min,因为在5之间的最小值应为5

db.test.update(
    { "a": 5 },
    { $min: { "b.0": 5 } },
    { upsert: true }
);

这不会引发错误,但现在我收到的文件是:

{ "a" : 5, "b" : { "0" : 5 } }

我需要一个5位于0位置的数组,但不是具有0属性的对象。

我怎样才能做到这一点?

1 个答案:

答案 0 :(得分:1)

你可以使用.bulkWrite()来实现这一点,它实际上是一个主要用例,说明为什么存在这种情况。它只向服务器发送“一个”实际请求,并且只有一个响应。它仍然是两个操作,但它们或多或少地捆绑在一起并且通常是原子的:

db.junk.bulkWrite([
  { "updateOne": {
    "filter": { "a": 1 },
    "update": { "$setOnInsert": { "b": [ 5,0 ] } },
    "upsert": true
  }},
  { "updateOne": {
    "filter": { "a": 1 },
    "update": { "$min": { "b.0": 5 } }
  }}
])

第一次运行会给你一个“upsert”,注意它在响应中是“插入”而不是“修改”:

{
        "acknowledged" : true,
        "deletedCount" : 0,
        "insertedCount" : 0,
        "matchedCount" : 1,
        "upsertedCount" : 1,
        "insertedIds" : {

        },
        "upsertedIds" : {
                "0" : ObjectId("5947c412d6eb0b7d6ac37f09")
        }
}

当然,文件看起来像是:

{
        "_id" : ObjectId("5947c412d6eb0b7d6ac37f09"),
        "a" : 1,
        "b" : [
                5,
                0
        ]
}

然后在实际案例中使用与$min不同的值运行:

db.junk.bulkWrite([
  { "updateOne": {
    "filter": { "a": 1 },
    "update": { "$setOnInsert": { "b": [ 5,0 ] } },
    "upsert": true
  }},
  { "updateOne": {
    "filter": { "a": 1 },
    "update": { "$min": { "b.0": 3 } }
  }}
])

回复:

{
        "acknowledged" : true,
        "deletedCount" : 0,
        "insertedCount" : 0,
        "matchedCount" : 2,
        "upsertedCount" : 0,
        "insertedIds" : {

        },
        "upsertedIds" : {

        }
}

哪个“匹配”2但当然$setOnInsert不适用,结果是:

{
        "_id" : ObjectId("5947c412d6eb0b7d6ac37f09"),
        "a" : 1,
        "b" : [
                3,
                0
        ]
}

就像它应该是