Обновление mongodb не работает с вложенным вложенным документом

Мои записи mongodb похожи на эту ссылку Обновление вложенного массива внутри массива mongodb и образец записи, указанные ниже, необходимо обновить поле во вложенном массиве «параметров» документа при условии, что оно удовлетворяет некоторым условиям (_id: «04», operations._id: «100» и operations.parameters.pid: «012»), это запрос на обновление ОБНОВЛЯЕТ неправильную вложенную запись (operations.parameters.pid: '011'), пожалуйста, помогите, где я ошибаюсь:

       {
"_id" : "04",
"name" : "test service 4",
"id" : "04",
"version" : "0.0.1",
"title" : "testing",
"description" : "test",
"protocol" : "test",
"operations" : [ 
    {
        "_id" : "99",
        "oName" : "test op 52222222222",
        "sid" : "04",
        "name" : "test op 52222222222",
        "oid" : "99",
        "description" : "testing",
        "returntype" : "test",
        "parameters" : [ 
            {
                "oName" : "Param1",
                "name" : "Param1",
                "pid" : "011",
                "type" : "582",
                "description" : "testing",
                "value" : "",
                "version" : 1.0
            }, 
            {
                "oName" : "Param2",
                "name" : "Param2",
                "pid" : "012",
                "type" : "58222",
                "description" : "testing",
                "value" : "",
                "version" : 2.0
            }
        ]
    }, 
    {
        "_id" : "100",
        "oName" : "test op 909090",
        "sid" : "05",
        "name" : "test op 90909",
        "oid" : "1009",
        "description" : "testing",
        "returntype" : "test",
        "parameters" : [ 
            {
                "oName" : "Param1",
                "name" : "Param1",
                "pid" : "011",
                "type" : "582",
                "description" : "testing",
                "value" : "",
                "version" : 1.0
            }, 
            {
                "oName" : "Param2",
                "name" : "Param2",
                "pid" : "012",
                "type" : "58222",
                "description" : "testing",
                "value" : "",
                "version" : 2.0
            }
        ]
    }, 
    {
        "_id" : "101",
        "oName" : "test op 52222222222",
        "sid" : "04",
        "name" : "test op 52222222222",
        "oid" : "99",
        "description" : "testing",
        "returntype" : "test",
        "parameters" : [ 
            {
                "oName" : "Param1",
                "name" : "Param1",
                "pid" : "011",
                "type" : "582",
                "description" : "testing",
                "value" : "",
                "version" : 1.0
            }, 
            {
                "oName" : "Param2",
                "name" : "Param2",
                "pid" : "012",
                "type" : "58222",
                "description" : "testing",
                "value" : "",
                "version" : 1.0
            }
        ]
    }, 
    {
        "_id" : "102",
        "oName" : "test op 909090",
        "sid" : "05",
        "name" : "test op 90909",
        "oid" : "1009",
        "description" : "testing",
        "returntype" : "test",
        "parameters" : [ 
            {
                "oName" : "Param1",
                "name" : "Param1",
                "pid" : "011",
                "type" : "582",
                "description" : "testing",
                "value" : "",
                "version" : 1.0
            }, 
            {
                "oName" : "Param2",
                "name" : "Param2",
                "pid" : "012",
                "type" : "58222",
                "description" : "testing",
                "value" : "",
                "version" : 2.0
            }
        ]
    }
]
   }

Мой запрос на обновление выглядит следующим образом:

 db.foo.update(
{ $and : [{'_id':'04'},
{'operations._id':'100' },
{'operations.parameters.pid': '012'}]},
{
    "$set": { 
        "operations.1.parameters.$.dummy": "foo"
    }
}
     )

Я использую mongodb 3.6.2, указанный в https://docs.mongodb.com/master/reference/operator/update/positional-filtered/ Пример записи по этой ссылке:

   {
"_id" : 1.0,
"grades" : [ 
    {
        "type" : "quiz",
        "questions" : [ 
            10.0, 
            8.0, 
            5.0
        ]
    }, 
    {
        "type" : "quiz",
        "questions" : [ 
            8.0, 
            9.0, 
            6.0
        ]
    }, 
    {
        "type" : "hw",
        "questions" : [ 
            5.0, 
            4.0, 
            3.0
        ]
    }, 
    {
        "type" : "exam",
        "questions" : [ 
            25.0, 
            10.0, 
            23.0, 
            0.0
        ]
    }
]
   }

Пример из этой ссылки

   db.student3.update(
   {},
        { $inc: { "grades.$[t].questions.$[score]": 2 } },
     { arrayFilters: [ { "t.type": "quiz" } , { "score": { $gte: 8 } } ], multi: true}
      )

ERror я получил от робо-3т:

 cannot use the part (grades of grades.$[t].questions.$[score]) to traverse the element ({grades: [ { type: "quiz", questions: [ 10.0, 8.0, 5.0 ] }, { type: "quiz", questions: [ 8.0, 9.0, 6.0 ] }, { type: "hw", questions: [ 5.0, 4.0, 3.0 ] }, { type: "exam", questions: [ 25.0, 10.0, 23.0, 0.0 ] } ]})

Пожалуйста помоги; С уважением, Крис


person chiku    schedule 26.01.2018    source источник
comment
Какая у вас версия?   -  person s7vr    schedule 26.01.2018
comment
Возможный дубликат обновления вложенного массива с помощью MongoDB   -  person s7vr    schedule 26.01.2018
comment
mongodb версии 3.4.3   -  person chiku    schedule 26.01.2018
comment
В старой версии невозможно обновить массивы, вложенные более чем на 1 уровень. А можно обновиться до 3.6?   -  person s7vr    schedule 26.01.2018
comment
но могу ли я узнать причину, по которой он обновляет неправильную запись, пожалуйста   -  person chiku    schedule 26.01.2018
comment
Конечно. У вас есть два фильтра массива {'operations._id':'100' }, {'operations.parameters.pid': '012'}. Последний индекс (0) переопределяет другой индекс (1), когда вы запрашиваете, чтобы найти соответствующий индекс. Итак, $ находит совпадение с последним, которое выводит индекс 0, потому что есть совпадение в первом элементе массива, и обновляет элемент массива с неправильным индексом. Поэтому вам нужно обновить до 3.6, чтобы он заработал.   -  person s7vr    schedule 26.01.2018


Ответы (1)


В вашей операции обновления

"$set": { 
        "operations.1.parameters.$.dummy": "foo"
    }

относится к 1-му элементу в операциях, который является элементом с "_id" : "100", и в массиве параметров, _ 3_ обновляет первый элемент в массиве.

Вам необходимо рассмотреть возможность использования mongodb 3.6, если вы хотите обновить элементы вложенного массива с помощью $ [], чтобы обновить все совпадающие элементы.

Один из возможных способов сделать это в версии 3.4 - получить требуемый вложенный документ и выполнить сопоставления и обновления на стороне приложения.

person Atish    schedule 26.01.2018
comment
не могли бы вы помочь мне сформулировать запрос на обновление в моем вопросе, спасибо Крис - person chiku; 26.01.2018