2016-12-30 10 views
1

Я хочу скопировать информацию о ценах в моем документе в массив prices[].Как массировать копию одного поля для первого объекта массива и обновлять документ в MongoDB?

var entitiesCol = db.getCollection('entities'); 
entitiesCol.find({"type": "item"}).forEach(function(item){ 
    item.prices = [ { 
     "value": item.price 
    }]; 
    entitiesCol.save(item); 
}); 

Это занимает слишком много времени, и некоторые поля не обновляются.

Я использую Mongoose на стороне сервера, и я также могу его использовать.

Что я могу сделать для этого?

+0

Какова ваша версия Mongoose и MongoDB? – chridam

+0

MongoDB 3.2.11 Я думаю, – Burak

ответ

1

В оболочке mongo вы можете использовать метод bulkWrite(), предназначенный для быстрой и эффективной реализации обновлений. Рассмотрим следующий пример:

var entitiesCol = db.getCollection('entities'), 
    counter = 0, 
    ops = []; 
entitiesCol.find({ 
    "type": "item", 
    "prices.0": { "$exists": false } 
}).snapshot().forEach(function(item){ 
    ops.push({ 
     "updateOne": { 
      "filter": { "_id": item._id }, 
      "update": { 
       "$push": { 
        "prices": { "value": item.price } 
       } 
      } 
     } 
    }); 
    counter++; 

    if (counter % 500 === 0) { 
     entitiesCol.bulkWrite(ops); 
     ops = []; 
    } 
}) 

if (counter % 500 !== 0) 
    entitiesCol.bulkWrite(ops); 

counter переменная выше есть управлять сыпучие обновления эффективно, если ваша коллекция велика. Он позволяет выполнять операции обновления и отправлять записи на сервер пакетами 500, что дает вам лучшую производительность, так как вы не отправляете каждый запрос на сервер всего один раз в каждые 500 запросов.

Для массовых операций MongoDB налагает default internal limit of 1000 операций на каждую партию, и поэтому выбор 500 документов хорош в том смысле, что у вас есть некоторый контроль над размером партии, а не для MongoDB накладывать значение по умолчанию, то есть для более крупных операций с величиной из 1000 документов.

+1

Должен ли я использовать snapshot()? – Burak

+0

@Burak Да, действительно, если это нечеткие коллекции и имейте в виду, что 'snapshot()' не гарантирует изоляции от вставки или удаления. – chridam

+0

Что делать, если я не хочу вдаваться в массив цен? Я просто хочу его установить. Потому что, если я запустил это во второй раз, массив будет иметь повторяющуюся цену – Burak