2015-07-25 2 views
1

Я получаю JSONObject и хотите perfom обновление MongoDB:Обновление множественного значения в массиве в MongoDB

JSONObject: "tablename":"1","inventar":[{"ean":"802.6180.222"},{"ean":"657.7412.878"}]}

Существующий документ (укороченный):

"tablename": "1", 
"accepted": false, 
"inventar": [ 
    { 
     "ean": "802.6180.222", 
     "accepted": "0" 
    }, 
    { 
     "ean": "657.7412.878", 
     "accepted": "0" 
    } 
], 

Мне нужно установить принятое значение «1» для каждого объекта в массиве (который находится в объекте invetar-jsonObject.)

Код:

app.post('/in_accept', function(request,response){ 
var jsonString=request.body.json; 
var jsonObj = JSON.parse(jsonString); 
var InUser = jsonObj.in_user; 
var InDate = jsonObj.in_date; 
var inventar = jsonObj.inventar; //is an Array 
var tablename = jsonObj.tablename; 
console.log(inventar); 
var query = {"tablename": tablename}; 
var update = {"accepted": true, CODE FOR UPDATING INVENTAR}; 
var options = {"upsert": false, "new": true}; 
     Move.findOneAndUpdate(query, update, options, 
     function(err,Move) { 
      console.log(Move); 
     }); 
response.json({"success": true}); 
}); 

Я знаю, что mongoDB предоставляет оператор «каждый», но я придерживался всего синтаксиса. Для каждого «ean» принятое значение должно быть установлено на «1».

Благодаря

ответ

1

Единственный реальный «нормальный» способ сделать это в стороне получения объекта с помощью .findOne() или варианта, то делая modfications в коде и вызове .save() (который не считаются «нормальным» как вопросы concurency juyst делает этот подход «умственный») заключается в том, чтобы выполнять «множественные» обновления или, по существу, один для каждого члена массива, который вы хотите изменить.

Ваш «лучший» подход заключается в том, чтобы прямо сейчас войти в основной драйвер и получить доступ к Bulk Operations API методы:

var input = { "tablename":"1","inventar":[{"ean":"802.6180.222"},{"ean":"657.7412.878"}]}, 
    bulk = Move.collection.initializeOrderedBulkOp(); 

// Build the statements 
input.inventar.forEach(function(inventar) { 
    bulk.find({ 
     "tablename": input.tablename, 
     "inventar.ean": inventar.ean 
    }).updateOne({ 
     "$set": { "inventar.$.accepted": 1 } 
    }); 
}); 

// Then execute 
bulk.execute(function(err,result) { 
    if (!err) { 
     response.json({ "sucess": true }) 
    } else { 
     // handle error 
    } 
}) 

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

Каждый «запрос» из .find() соответствует элементу в массиве и возвращает это «индекс» значение через р ositional $ operator, который используется в «обновлении» часть способа, чтобы $set значения в согласованной позиции индекса ,

+0

спасибо, работает как epxected. Каждый раз, когда я использую MongoDB гораздо глубже, это ужасно. Так много апи вокруг ... – Piet

+0

@Piet Я лично считаю это довольно простым. Как будто я знаю, что я регулярно хочу обновлять несколько вещей, таких как вы здесь, то я либо принимаю несколько процессов обновления, как описано выше, либо использует другую коллекцию, которую я могу просто обновить с помощью '{" multi ": true}' .I зависит от что лучше всего подходит для меня. У меня многолетний опыт работы с SQL Relational (не молодой), и я использую решения NoSQL, такие как MongoDB, чтобы лучше соответствовать случаям, когда реляционная модель не применяется. В противном случае я использую реляционный движок. –

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