问题 我在更新时使用$ set和$ inc做错了什么


我在尝试这个 mongodb控制台

db.foobar.update( 
  { name: "Foobar" },
  { 
    $set : { foo: { bar: 'bar' }, 
    $inc: { 'foo.count': 1 } 
  } 
}, true)

它以“ok”返回,但是 db.foobar.find(),返回一个空记录集。我试图 upsert 一个文件,所以它看起来像:

name: Foobar
foo: {
  bar: 'bar'
  count: 1
}

如果doc不存在,则创建一个计数为1.否则,只需增加计数。为什么不在上面工作?


1651
2018-05-27 10:14


起源



答案:


在我看来,您的代码实际上是尝试设置文档的$ inc字段,而不是在foo.count字段上使用$ inc修饰符。这可能是你想要的:

db.foobar.update(
    { name: "Foobar" }, 
    {
        $set: { 'foo.bar': 'bar' }, 
        $inc: { 'foo.count': 1 } 
    }, true)

希望这可以帮助。


13
2018-05-27 15:51



这样可行。但为什么这不起作用: db.foobar.update( { name: "Foobar" }, { $set: { foo: { bar: 'bar' } }, $inc: { 'foo.count': 1 } }, true) 似乎在字符串中设置将使其工作。但我想知道为什么 - Christian Fazzini
我没注意到! shell提供的错误消息是“更新中存在冲突的mod”。对我来说,这表明$ set作为一个整体在'foo'子文档上运行,因此你不能在'foo'或其任何属性上使用$ inc,例如'foo.count'。我猜想在'foo.bar'上使用$ set和在'foo.count'上使用$ inc是有效的,因为这两个修饰符针对文档的不相交部分。 - idrarig


答案:


在我看来,您的代码实际上是尝试设置文档的$ inc字段,而不是在foo.count字段上使用$ inc修饰符。这可能是你想要的:

db.foobar.update(
    { name: "Foobar" }, 
    {
        $set: { 'foo.bar': 'bar' }, 
        $inc: { 'foo.count': 1 } 
    }, true)

希望这可以帮助。


13
2018-05-27 15:51



这样可行。但为什么这不起作用: db.foobar.update( { name: "Foobar" }, { $set: { foo: { bar: 'bar' } }, $inc: { 'foo.count': 1 } }, true) 似乎在字符串中设置将使其工作。但我想知道为什么 - Christian Fazzini
我没注意到! shell提供的错误消息是“更新中存在冲突的mod”。对我来说,这表明$ set作为一个整体在'foo'子文档上运行,因此你不能在'foo'或其任何属性上使用$ inc,例如'foo.count'。我猜想在'foo.bar'上使用$ set和在'foo.count'上使用$ inc是有效的,因为这两个修饰符针对文档的不相交部分。 - idrarig


在您提供的代码段中,您在$ set对象之后缺少一个结束大括号。但那是个问题。

我不相信你可以在一个交易中设置和增加相同的子文档。 由于count是foo下的成员,因此它不会存在。我尝试以下操作时出现的错误:

db.foobar.update( 
   { name: "Foobar" },
   { 
     $set : { foo: { bar: 'bar' }}, 
     $inc: { 'foo.count': 1 } 
   } 
}, true)

是“更新中的冲突模式”。 也许你可以这样建模:

db.foobar.update({name:"foobar"},{$set:{foo:{bar:"bar"}},$inc:{count:1}},true);

或者如果您愿意:

db.foobar.update({name:"foobar"},{$set:{foo:{bar:"bar"}},$inc:{"counts.foo":1}},true);

1
2018-05-27 19:55





所以我现在正在尝试:

var doc = {
            "name": "thename",
            "organisation": "theorganisation"
        }, // document to update. Note: the doc here matches the existing array
    query = { "email": "email@example" }; // query document
    query["history.name"] = doc.name; // create the update query
    query["history.organisation"] = doc.organisation;
    var update = db.getCollection('users').findAndModify({
        "query": query,
        "update": { 
            "$set": { 
                "history.$.name": doc.name,
                "history.$.organisation": doc.organisation
            },
            "$inc": { "history.$.score": 5 } //increment score
        }
    });
    if (!update) {
        db.getCollection('users').update(
            { "email": query.email },
            { "$push": { "history": doc } }
        );
    }
    db.getCollection('users').find({ "email": "email@example" });

这更新了 score,如果它不存在,则将其添加到对象,但它似乎更改了所有对象 names到doc.name(在本例中为“thename”)。

如果文档还不存在,我还没有进入


0
2018-06-14 19:37