2013-08-21 4 views
0

У меня есть документ сортов:Как обновить 2 определенных элемента в массиве с двумя разными значениями?

{ _id:ObjectID, list:Array } 

И список содержит элементы формы (которые я буду ссылаться как listElement):

{ _id:ObjectID, time:Number } 

Я хочу, чтобы обновить время подполе 2 конкретных спискаElements каждый со своим отдельным значением. У меня есть доступ к _ID из спискаElements.

Связанная вещь об этой проблеме: было бы лучше преобразовать список из массива в объект, ключи которого являются значениями _id? поэтому я бы сделал db.update ((_id: «Document id»}, {"list.423rfasf2q3.time": 200, "list.fjsdhfksjdh2432.time": 100})?

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

ответ

2

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

Вы не хотите помещать данные в свои ключевые значения, лучше оставить их такими, какие они есть. Нет подходящего способа сопоставления ключевых значений вне $ exists и даже того, что не поддерживает подстановочные знаки. Поэтому вам нужно будет получить ObjectId, преобразовать его в строку, co ncatenate это в ключ, затем запрос для документов, где этот ключ существует. Гораздо проще просто поместить значение в документ в массив. Кроме того, нет возможности индексировать значения ключей в MongoDB, поэтому, если вы хотите индексировать свои данные, вам нужно будет иметь его в массиве как элемент данных.

Редактировать включить позиционный пример матча

Сначала вставьте два документ

> db.test.insert({list: [ {_id: new ObjectId(), time: 1234}, {_id: new ObjectId(), time: 4556} ] }) 
> 

Продемонстрировать, что они оба там

> db.test.find() 
{ "_id" : ObjectId("5215036749177daf439a2ffe"), "list" : [{ "_id" : ObjectId("5215036749177daf439a2ffc"), "time" : 1234 }, { "_id" : 
ObjectId("5215036749177daf439a2ffd"), "time" : 4556 } ] } 
> 

Показать, что если мы делаем нормальный фильтр массива мы получаем все элементы массива

> db.test.find({"list._id":ObjectId("5215036749177daf439a2ffc")}) 
{ "_id" : ObjectId("5215036749177daf439a2ffe"), "list" : [ { "_id" : ObjectId("5215036749177daf439a2ffc"), "time" : 1234 }, { "_id" : 
ObjectId("5215036749177daf439a2ffd"), "time" : 4556 } ] } 
> 

Продемонстрировать, что мы можем использовать оператор $ только возвращает первый элемент массива, который был согласованный

> db.test.find({"list._id":ObjectId("5215036749177daf439a2ffc")}, {_id: 0, "list.$": 1}) 
{ "list" : [ { "_id" : ObjectId("5215036749177daf439a2ffc"), "time" : 1234 } ] } 
+0

Я действительно не хочу, чтобы сделать отдельные запросы, он перегрузит мою систему транзакций слишком много. И снова действия независимы друг от друга, но я должен вернуть 1 клиенту обновление для всех операций, поэтому я захотел соединить вызовы. Почему я не могу индексировать подполя подполей документов? – Discipol

+0

Проблема заключается в том, что нет синтаксиса, чтобы сообщить MongoDB о выполнении условного обновления (если _id = x, тогда установите значение y, если _id = a, а затем установите значение b). Обновление документа относительно маловероятно, разница между обновлением двух документов в одном вызове или двумя документами будет очень мала при двух вызовах - вы можете подумать о том, что ваша система не сможет обрабатывать том. Индексирование индекса не будет работать, если вы поместите «ObjectId» в ключ, потому что вы должны установить свой индекс по определенному имени ключа. Если вы вставляете 'ObjectId' в ключ, тогда нет никакого имени ключа, чтобы включить ваш индекс. – Mason

+0

Что делать, если я просто индексирую подполе «список»? это поможет только при получении самого «подполя» списка? все это? – Discipol