2016-07-19 3 views
0

мне нужно обновить документ MongoDB, который выглядит следующим образом:Update MongoDB документ с вложенными массивами поддокументами

{ 
    "_id" : ObjectId("A"), 
    "participant" : "John Doe", 
    "roles" : [{ 
     "roleId" : ObjectId("AA"), 
     "responsibilities" : [{ 
      "_id" : ObjectID("AAA"), 
      "name" : "resp 1" 
     }, { 
      "_id" : ObjectID("AAB"), 
      "name" : "resp 2" 
     }] 
    }, { 
     "roleId" : ObjectId("AB"), 
     "responsibilities" : [] 
    }] 
} 

Обновления приходят в двух формах:

  • Удалить все роли суб- документы, которые имеют нулевые обязанности ... это должно удалить подпункт роли с _id = AB
  • Добавить новую роль, если она еще не существует: { "roleId" : ObjectId("AC"), "responsibilities" : [] }
+0

делает второе обновление, добавляет новую роль в документы, в которых вы удалили только субдокумент в первом обновлении? или вы используете только второе обновление для документов, у которых не было поддокумента с нулевыми обязательствами? – devonJS

+0

@devonJS два действия обновления будут выполняться отдельно и не связаны друг с другом. Иногда мне может потребоваться добавить новые роли, и мне нужно убедиться, что эта роль еще не существует. Это может быть добавлено как ограничение по индексу, но мне по-прежнему необходимо выполнить проверку по другим причинам. В других случаях я хочу удалить подзапрос роли, только если роль имеет нулевые обязанности. –

ответ

1

Ваше первое обновление:

db.getCollection('collection').update({}, 
    { 
     $pull: { 
      'roles': { 
       'responsibilities': {$size: 0} 
      } 
     } 
    }, {multi: true}) 

В основном, удаляет элемент любого (это где много: верно приходит в) «роли» массив «обязанности» является пустым массивом (или размер 0)

Ваше второе обновление, предполагая, что «новую роль» является роль с пустой массив обязанности:

db.getCollection('collection').update(
    { 
     'roles': { 
      $not: { 
       $elemMatch: { 
        'roleId': ObjectId("AC") 
       } 
      } 
     } 
    }, 
    { 
     $push: { 
      'roles': { 
       'roleId': ObjectId("AC"), 
       'responsibilities' : [] 
      } 
     } 
    }, {multi: true}) 

Находит документы, у которых нет массива ролей, где у элемента есть пустой массив обязанностей, а затем добавляет новую роль в новый ObjectId или вы можете указать его самостоятельно.

Я проверил это на небольшой коллекции из 5 документов и, похоже, работает, сообщите мне, нужно ли вам какое-либо разъяснение или если оно не работает.

Стоит отметить, что запрос массива, в котором вы должны итерации по массиву $elemMatch, - это то, что вы ищете. При изменении, и вам нужно итерации через массив $pull - это то, что вы хотите использовать.

+0

для второго обновления, я хочу добавить роль с определенным идентификатором, если эта роль еще не существует в массиве ролей. Должен ли я не искать существующую роль с совпадающим идентификатором, а не с ролью с пустым массивом полномочий? –

+0

@WebUser извините, я неправильно понял ваш вопрос, см. Изменения, которые я сделал выше, теперь он ищет роль, и если он не может ее найти, вставляет эту роль в – devonJS

+0

. Это намного ближе к тому, что я был находясь в поиске. Я проверю его в ближайшее время. Есть ли способ перенаправить обновление на конкретный документ, а не на любые или все документы *? Еще один вопрос - могу ли я '$ elemMatch' использовать несколько идентификаторов ролей вместо одного? –

Смежные вопросы