MongoDB обновляет вложенный элемент по динамическому идентификатору

Эй, я пытаюсь обновить вложенный объект в моей MongoDB.

Их структура

[
 {
  "_id": "5871010d1ff9831574e7178d",
  "created_at": "2017-01-07T14:54:05.791Z",
  "updated_at": "2017-01-07T14:54:05.791Z",
  "place_id": "ChIJ1eTO6eS1vkcRL_mX2RWUKo4",
  "name": "Kunstwerk Restaurant Gummersbach",
  "__v": 0,
  "cooks": [],
  "menus": [
   {
    "58727068ba8d6c04a0ea331f": [
      {
        "intolerances": {
           "intolerance" : "false"
            ...
          },
        "nutritiondata" : [
          {...}
         ],
         "cookname": "[email protected]",
         "menuname": "MenünameX"
      }
    ]
  }
]

Вложенный идентификатор в меню — это еще один идентификатор документа MongoDB, который создается динамически.

Я пытаюсь обновить имя меню, но не могу получить к нему доступ, так как монго всегда возвращает ноль или не находит элемент, поскольку ему нужно искать только ключ, а не пару ключ-значение.

Что я тестировал до сих пор:

db.restaurants.update({ 'menus.58727068ba8d6c04a0ea331f', { $set : {"menus.$.menuname" : "test"}}});

db.restaurants.findOne({ 'menus.58727068ba8d6c04a0ea331f' : "58727068ba8d6c04a0ea331f"});

db.restaurants.find({ menus : { $elemMatch : {"58727068ba8d6c04a0ea331f": "58727068ba8d6c04a0ea331f" }}});

db.restaurants.findOne({ menus : { $eq : "58727068ba8d6c04a0ea331f" }});

person Lukas S    schedule 08.01.2017    source источник


Ответы (2)


Используйте метод $set, как показано ниже:

db.restaurants.update({"_id":"5871010d1ff9831574e7178d"}, {$set: {"menus.58727068ba8d6c04a0ea331f.0.menuname":"test"});

Это будет работать, только если вы знаете индекс элемента в обновляемом массиве. Проверьте эту страницу, у него есть несколько хороших примеров по обновлению многоуровневых вложенных массивов, надеюсь, это поможет.

person Supradeep    schedule 08.01.2017
comment
спасибо за ответ, так что я мог бы использовать $ в качестве заполнителя для объекта? Например, меню.ID.$.menuname? Также в вашем примере mongoshell отвечает только с помощью ... . Так это не сработало? - person Lukas S; 08.01.2017
comment
Он ожидает поле массива в запросе. Вы получаете какую-либо ошибку? - person Supradeep; 08.01.2017
comment
Нет, только 3 балла. Я думаю, что это ожидающий результат... Но сообщение об ошибке не появляется - person Lukas S; 08.01.2017
comment
ааа я вижу твою ошибку. Рестораны были написаны с ошибкой, и одна скобка отсутствовала. теперь есть сообщение об ошибке. Слишком много позиционных (т.е. '$') элементов в меню пути.$.58727068ba8d6c04a0ea331f.$.menuname - person Lukas S; 09.01.2017
comment
Ok. Одна вещь, которую вы можете сделать, это, если вы знаете индекс массива, который вы хотите обновить, db.restaurents.update({"_id":"5871010d1ff9831574e7178d"}, {$set: {"menus.58727068ba8d6c04a0ea331f.0.menuname":"test"}); - person Supradeep; 09.01.2017
comment
Я обновил свой ответ, проверьте, работает ли он, и проверьте ссылку, которую я упомянул в ответе, это может помочь. - person Supradeep; 09.01.2017
comment
Спасибо за вашу помощь :) нашел решение этой ночью самостоятельно с вашим советом - person Lukas S; 09.01.2017
comment
Прохладный . Приятно это знать, кстати, каков ответ? - person Supradeep; 09.01.2017

Итак, благодаря suzo я нашел решение. Работающий код MongoShell:

db.restaurants.update({"_id" : ObjectId("5871010d1ff9831574e7178d")}, {$set: {"menus.58727068ba8d6c04a0ea331f.0.menuname" : "testName"}});

ОБНОВЛЕНИЕ: поскольку мое поле имеет смешанный тип, оно не обновляется без пометки!. Итак, вот полный правильный код:

 Restaurant.findOne({ _id : req.body.r_id }, function(error, restaurant){
    if(error) console.log(error);

    for(var i = 0; i < restaurant.menus.length; i++){
          restaurant.markModified('menus');
        if(restaurant.menus[i][req.params.id] != undefined){
            restaurant.menus[i][req.params.id].menuname = req.body.name;
        }

        if(i == restaurant.menus.length-1){
            restaurant.save();
            res.json(jObj);
        }
    }

  })
person Lukas S    schedule 09.01.2017
comment
Прохладный. Похоже, это то же самое, что и мой ответ, но мой вопрос: что, если мы не знаем индекс массива? - person Supradeep; 09.01.2017
comment
обновил мой ответ :) столкнулся с проблемой все время, так как я понял свой первый ответ. Поэтому мое решение состоит в том, чтобы посмотреть, какой ключ не является неопределенным. Поскольку у меня там только уникальные ключи, этот метод работает. - person Lukas S; 09.01.2017