2016-10-25 3 views
1

Я широко использовать встроенные документы в моей базе данных MongoDB, и я бегу в проблемы скорости при попытке добавить дополнительные данные:Добавление дополнительных полей для вложенного документа

В качестве примера у меня есть документ, который выглядит немного как это:

{ 
     "date" : <<the date>> 
     "name" : "thisName" 
     "basket": [ 
        { 
        "stock": "IBM", 
        "quantity": 1000.0, 
        "profit" : 10:0, 
        }, 
        ... 
        { 
        "stock": "MSFT", 
        "quantity": 2000.0, 
        "profit" : 30:0, 
        }, 

       ] 
} 

То, что я хочу сделать, это добавить 5 новых полей вложенных документов, как это:

{ 
     "date" : <<the date>> 
     "name" : "thisName" 
     "basket": [ 
        { 
        "stock": "IBM", 
        "quantity": 1000.0, 
        "profit" : 10:0, 
        "new_1" : 10:0, 
        "new_2" : 10:0, 
        "new_3" : 10:0, 
        "new_4" : 10:0, 
        "new_4" : 10:0, 
        "new_5" : 10:0 
        }, 
        ... 
        { 
        "stock": "MSFT", 
        "quantity": 2000.0, 
        "profit" : 30:0, 
        "new_1" : 10:0, 
        "new_2" : 10:0, 
        "new_3" : 10:0, 
        "new_4" : 10:0, 
        "new_4" : 10:0, 
        "new_5" : 10:0 
        }, 

       ] 
} 

Я начал делать это с помощью находку () .update_one() в цикле for, идентифицируя каждый внедренный документ явно и используя документ, явно используя «$ set». Этот подход работает, но он очень медленный. Если моя коллекция была небольшой, я уверен, что это не имеет значения, но поскольку она огромна (100 миллионов миллионов документов). Это, вероятно, так медленно, потому что весь документ нужно перемещать каждый раз, когда я добавляю набор полей. Имея это в виду, я попытался добавить новые поля во все вложенные документы за один раз. Я сделал это, оставив запрос на поиск пустым и удалив позиционный $ из команды «$ set». Немного, как это (в PyMongo):

bulk.find({"date": dates[i], 
      "strategyId": strategyInfo[siOffset[l]][ID] 
      }).update({ 
        "$set": { 
          "basket.new_1": 0.0, 
          "basket.new_2": 0.0, 
          "basket.new_3": 0.0, 
          "basket.new_4": 0.0, 
          "basket.new_5": 0.0 
         } 
         }) 

Этот подход, кажется, выдаст ошибку cannot use the part (basket of basket.new_5) to traverse the element ({basket:......

ли кто-нибудь может дать некоторое представление о том, что я делаю не так? Возможно ли это сделать?

+0

возможно дубликат [Как обновить несколько элементов массива в MongoDB] (http://stackoverflow.com/questions/4669178/how-to-update-multiple -array-elements-in-mongodb) –

+0

Я согласен, что это возможно дубликат, но MongoDB значительно изменился с 2011 года. –

ответ

1

Вы можете использовать такую ​​рекурсивную функцию.

Сначала найти все данные для обновления

db.collection('game_users').find(
    {"date": dates[i],"strategyId": strategyInfo[siOffset[l]][ID]} 
).toArray(function(err, data) { 
    var i=0; 
    function data_Update(){ 
     if(i!=data.length){ 
      db.collection('game_users').update(
       {"date": dates[i],"strategyId": strategyInfo[siOffset[l]][ID]}, 
       { $set : { 
        "basket.new_1": 0.0, 
        "basket.new_2": 0.0, 
        "basket.new_3": 0.0, 
        "basket.new_4": 0.0, 
        "basket.new_5": 0.0 
        } 
       }, 
       function(err, resp) { 
        i++; 
        data_Update(); 
       } 
      ); 
     } 
    } 
} 
);` 
+0

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

+0

Когда старый пользователь регистрируется в вашем приложении .. в это время u проверьте это поле, если нет в профиле пользователя, вы можете добавить ... i вещь без цикла невозможна .... –

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