2014-08-04 1 views
0

У меня есть инвентарь коллекции с именем, где у меня есть несколько документов, которые имеют значение для каждого докаОбновления несколько документов/добавить ключи и ценности в новый массив

{ "apples": 2 ,"oranges": 3, "carrots": 5 } 
{ "apples": 4, "oranges": 6, "carrots": 9 } 

Как обновить вдвинуть фрукты в к один массив на несколько документов, например, так:

{ "fruits": { "apples":2 ,"oranges":3 }, "carrots": 5 } 
+1

Не могли бы вы лучше объяснить, что делать? Потому что я не понимаю, почему вы говорите о массиве. Я вижу только список документов. Спасибо – MetalMad

+0

Что мне нужно, чтобы принести все фрукты под общим ключом Фрукты в качестве вспомогательного документа. – pjsuccess

ответ

1

Первое, что нужно отметить, что пример вы даете не массив, а просто суб-документ для «плодов», который имеет разные ключи. «Массив» в MongoDB будет выглядеть следующим образом:

{ "fruits": [{ "apples":2 } , { "orange":3 }], "carrot": 5 } 

Кроме того, в стороне от термина «фрукты» субъективны, так как нет другого идентификатора вы должны указать «список» вещей, которые квалифицируются как фрукты , другая вещь, которую следует учитывать, заключается в том, что в настоящее время в MongoDB нет реального способа ссылаться на существующее значение поля при обработке обновления.

Что это значит, вам нужно, чтобы каждый документ извлекал данные, чтобы иметь возможность работать с подобной «переструктурой», которую вы хотите. Это, по существу, означает объединение результатов, выполняющих операцию .update() для каждого документа.

Bulk API для MongoDB 2.6 и выше, может иметь некоторую помощь здесь, где по крайней мере, «писать» операции в базе данных могут быть отправлены в пакетах, а не один, в то время:

var bulk = db.collection.initializeOrderedBulkOp(); 
var count = 0; 

var fruits = ["apples","oranges"]; 
var unset = {}; 

fruits.forEach(function(fruit) { 
    unset[fruit] = 1; 
}); 


db.collection.find({}).forEach(function(doc) { 

    var fields = []; 
    fruits.forEach(function(fruit) { 
     if (doc.hasOwnProperty(fruit)) { 
      var subDoc = {}; 
      subDoc[fruit] = doc[fruit]; 
      fields.push(subDoc); 
     } 
    }); 

    bulk.find({ "_id": doc._id }).updateOne({ 
     "$unset": unset, "$push": { "fruits": { "$each": fields } } 
    }); 
    count++; 

    if (count % 1000 == 0) { 
     bulk.execute(); 
     var bulk = db.collection.initializeOrderedBulkOp(); 
    } 

}); 

if (count % 1000 != 0) 
    bulk.execute(); 

Это также использует модификатор $each для $push, чтобы добавить сразу несколько записей массива. Оператор $unset может быть безопасно вызван для полей, которые не существуют в документе, поэтому нет необходимости проверять их присутствие в документе, как это требуется при построении массива элементов до $push.

Конечно, если вы на самом деле хотите, документ, как то, что вы дали пример того, что это на самом деле не является массивом, то вы строите по-разному с $set оператора:

var fields = {}; 
    fruits.forEach(function(fruit) { 
     if (doc.hasOwnProperty(fruit)) 
      fields[fruit] = doc[fruit]; 
    }); 

    bulk.find({ "_id": doc._id }).updateOne({ 
     "$unset": unset, "$set": { "fruits": fields } 
    }); 

В любом случае это нужно цикл существующей коллекции. Нет операции, позволяющей «взять» существующее значение в документе и «использовать его», чтобы установить новое значение с точки зрения сервера.

+0

Привет, Нил, спасибо. Я просто изучаю Mongodb. Вы правы, это субдокумент. Мне нужно сгруппировать все виды фруктов в ключе Fruit. Там есть какая-либо короткая стрижка или любая прямая операция CRUD для обновления mutttiple docs без каких-либо других кодов. Цените свое время. Спасибо – pjsuccess

+0

Ответ Нила указывает, что нет способа (в настоящее время, 2.6) ссылаться на существующее значение полей в документе для обновления, за некоторыми исключениями для определенных операций, таких как '$ inc'. Вам нужно будет что-то сделать в соответствии с тем, что предлагает Нейл. – wdberkeley

+0

@pjsuccess В ответ объясняется, что MongoDB в настоящее время не может использовать существующее значение одного поля для обновления другого поля в атомном обновлении. Например, множество A = B. Подход, как показано, требует получения информации о документе для выпуска отдельного обновления. Это, по сути, то, что вам нужно делать. –

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

  • Нет связанных вопросов^_^