簡體   English   中英

MongoDB:子數組的更新屬性只更新第一個元素

[英]MongoDB: Update property of subarray just updates the first element

匹配的元素看起來像這樣:

{
    "_id": {
        "$oid": "519ebd1cef1fce06f90e3157"
    },
    "from": "Tester2",
    "to": "Tester",
    "messages": [
        {
            "username": "Tester2",
            "message": "heeey",
            "read": false
        },
        {
            "username": "Tester",
            "message": "hi!",
            "read": false
        },
        {
            "username": "Tester2",
            "message": "test",
            "read": false
        }
    ],
}

現在我嘗試將read屬性設置為用戶名不等於Tester的子元素的當前日期:

var messages = db.collection('messages');
messages.update(
{
    _id: new BSON.ObjectID("519ebd1cef1fce06f90e3157"),
    messages: {
        $elemMatch: { username: { $ne: "Tester" } }
    }
},
{ $set: { 'messages.$.read': new Date() } },
{ multi: true }, function(error, result) {
    console.log(error);
    console.log(result);
});

但只有第一個消息子元素read屬性更新:

{
    "_id": {
        "$oid": "519ebd1cef1fce06f90e3157"
    },
    "from": "Tester2",
    "to": "Tester",
    "messages": [
        {
            "username": "Tester2",
            "message": "heeey",
            "read":  {
                "$date": "2013-01-01T00:00:00.000Z"
            }
        },
        {
            "username": "Tester",
            "message": "hi!",
            "read": false
        },
        {
            "username": "Tester2",
            "message": "test",
            "read": false
        }
    ],
}

代碼有什么問題? 我將 node.js v0.10.8 和 MongoDB v2.4.3 與node-mongodb-native一起使用。

您的代碼沒有任何問題; $運算符包含第一個匹配數組元素的索引。 {multi: true}選項僅使update適用於多個文檔,而不是數組元素。 要在一次update更新多個數組元素,您必須通過數字索引指定它們。

所以你必須做這樣的事情:

messages.update(    
    {
        _id: new BSON.ObjectID("519ebd1cef1fce06f90e3157")
    },
    { $set: { 
        'messages.0.read': new Date(),
        'messages.2.read': new Date()
    } },
    function (err, result) { ... }
);

這類似於問題: How to Update Multiple Array Elements in mongodb

var set = {}, i, l;
for(i=0,l=messages.length;i<l;i++) {
  if(messages[i].username != 'tester') {
    set['messages.' + i + '.read'] = new Date();
  }
}

.update(objId, {$set:set});

我認為在這種情況下可以使用 ArrayFilters

我知道回答這個問題有點晚了,但是如果您使用 $[] 運算符,它就可以解決問題。

var messages = db.collection('messages');
messages.update(
{
    _id: new BSON.ObjectID("519ebd1cef1fce06f90e3157"),
    messages: {
        $elemMatch: { username: { $ne: "Tester" } }
    }
},
{ $set: { 'messages.$[].read': new Date() } },
{ multi: true }, function(error, result) {
    console.log(error);
    console.log(result);
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM