2016-01-03 2 views
1

Я довольно новичок в mongodb и самообучении. С недавних пор я немного застрял на этом. Я хотел бы обновить вложенный документ. Я работал над ним, получая полный документ и обновляя все это, но мне нужно решение, в котором я могу обновить его одним выстрелом. Я сделал следующий упрощенный пример:Как обновить вложенный объект в mongodb

db.test.insert({ 
    'name': 'someSchool', 
    'classes': [ 
     { 
      'name': 'someClass', 
      'students': [ 
       { 
        'name': 'Jack', 
        'coolness' : 7 
       } 
      ] 
     } 
    ] 
}); 

Здесь массивы имеют только одну запись для простоты, вы понимаете, мы обычно имеем больше ...

db.test.find({ 
    'name' : 'someSchool', 
    'classes' : { 
     $elemMatch: { 
      'name': 'someClass', 
      'students.name' : 'Jack' 
     } 
    } 
}); 

Это найти работы! Это здорово, поэтому теперь я хочу использовать его в обновлении, в котором я застрял. Что-то вроде этого??

db.test.update({ 
    'name' : 'someSchool', 
    'classes' : { 
     $elemMatch: { 
      'name': 'someClass', 
      'students.name' : 'Jack' 
     } 
    } 
}, { 
    '$set' : { 'classes.students.coolness' : 9} 
}); 

Так что это не работает, и теперь я застрял в нем :) Надеюсь, кто-то здесь может помочь.

Сторона примечания: Я использую мангуст. Если вы, ребята, говорите мне, что лучше изменить схему, чтобы сделать ее проще, я могу.

Обновление с указанной пометки как дублирующееся: в заданном вопросе имеется только 1 уровень вложенности, и проблема решена с использованием точечной нотации. Здесь есть 2 уровня. Я принял ответ, который объясняет, что он не поддерживается и который дает правильное обходное решение.

+0

Возможный дубликат [Как я могу вытащить поддокументы из массива] (http://stackoverflow.com/questions/34564195/how-can- я-джемпер поддокументы-из-ан-массива) – styvane

ответ

1

Как уже упоминалось, here сейчас невозможно обновить массивы с двумя уровнями.

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

{ 
    "name" : "someSchool", 
    "classes" : { 
      "someClass" : { 
        "students" : [ 
          { 
            "name" : "Jack", 
            "coolness" : 7 
          } 
        ] 
      } 
    } 
} 

Затем вы можете использовать positional operator для обновления конкретного элемента массива. Но имейте в виду, что оператор positional обновляет только первый элемент в массиве, который соответствует запросу.

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

db.test.update({ 
    'classes.someClass.students' : {   
    $elemMatch: { 
     'name' : 'Jack'   
    }  
    } 
}, {  
    '$set' : { 
    'classes.someClass.students.$.coolness' : 9 
    } 
}); 
Смежные вопросы