#mongodb
#mongodb
Вопрос:
У меня есть коллекция Spots:
- spotId
- name
и коды:
- codeId
- spotId
- code
Я хочу представить поле
- spotName
к кодам (и присоедините по spotId).
Как мне обновить все мои существующие документы в оболочке mongo?
Когда я пытаюсь использовать $ lookup, я всегда получаю весь документ Spot, а не только поле name.
Ответ №1:
Если вы хотите получить формат, в котором вы получаете spotName
в каждом документе, вы можете использовать конвейер агрегации. $lookup
было хорошим началом. Здесь он генерирует полный массив, который вы можете $unwind
и спроецировать необходимый материал
[{$lookup: {
from: 'Spots',
localField: 'spotId',
foreignField: 'spotId',
as: 'new_field'
}},
{$unwind: '$new_field'},
{$project: {
codeId: 1,
spotId: 1,
code: 1,
spotName: '$new_field.name'
}}
]
Приведенное выше решение представляет случай, если вам нужно просто использовать результаты.
Если вы действительно хотите выполнить update
для коллекции, единственным способом было бы написать find
, который просматривает все документы в кодах, а затем, как только он получает документ, выполняет поиск документа в Spots с помощью findOne
, а затем выдает инструкцию update .
Codes.find().each(function(err, doc) {
Spots.findOne({spotId: doc.spotId}, function (err, item) {
Codes.update({codeId: doc.codeId}, {$set: {spotName: item.name}}, function (err, res) {})
})
});
Ответ №2:
Вам нужно будет запустить скрипт
var spotMap ={}; Spots.find({},{spotId:1,name:1}).each(function(spot){spotMap[spot.spotId]=spot.name}); Codes.find({}).each(function(code){code.spotName=spotMap[code.spotId]; db.Codes.save(code);});
Также обратите внимание, что если коллекция слишком большая, возникнут проблемы при извлечении всех данных сразу из-за ограничения mongo на 16 МБ данных в памяти, и тогда вам придется запускать скрипт пакетами несколько раз.
Codes.find({}).limit(1000).each(function(code){//do normal stuff}
Codes.find({}).skip(1000).limit(1000).each(function(code){//do normal stuff}
Codes.find({}).skip(2000).limit(1000).each(function(code){//do normal stuff}
и так далее….