У меня есть document
Users
с свойством storage
определенным как массив ObjectId
ссылается другой document
под названием Storage
. Я пытаюсь получить конкретного пользователя, а затем возвращать информацию о хранилищах внутри массива.
Это мой код:
module.exports.storageDetail = function(req, res) {
User.findOne({'userId': req.user.userId}, 'storages').then(function(data){
var storageArray = [];
data.storages.forEach(function(record){
Storage.findOne({_id: record}, function(err, storage){
storageArray.push(storage);
});
});
return Promise.all(storageArray);
}).then(function(storageList){
res.render('storage_template', {
storage: storageList
});
console.log(storageList);
});
}
Но после выполнения, storageList
- пустой массив.
Я новичок в node.js и, пожалуйста, дайте мне знать, если мне нужно предоставить дополнительную информацию.
Итак, главное, что вам нужно .exec()
, чтобы вернуть Promise. Вот почему ваша попытка не удалась. Но есть и синтаксически более сильные подходы.
Вместо этого используйте .map()
и вызовите .exec()
чтобы вернуть Promise
User.findOne({'userId': req.user.userId}, 'storages').then(function(data){
var storageArray = data.storages.map(function(id) {
return Storage.findOne({_id: id }).exec()
});
return Promise.all(storageArray);
}).then(function(storageList){
res.render('storage_template', {
storage: storageList
});
console.log(storageList);
});
Или вместо этого используйте $in
с .find()
где метод возвращает массив, и оператор позволяет указать массив вещей, которые должны соответствовать:
User.findOne({'userId': req.user.userId}, 'storages').then(function(data){
return Storage.find({ "_id": { "$in": data.storages } }).exec();
}).then(function(storageList){
res.render('storage_template', {
storage: storageList
});
console.log(storageList);
});
Это также похоже на то, что вы могли бы просто использовать .populate()
User.findOne({'userId': req.user.userId}, 'storages')
.populate('storages')
.then(function(data) {
res.render('storage_template', {
storage: data.storages
});
console.log(data.storages);
});
Но в вашем вопросе неясно, действительно ли они определены как ссылки на модель Storage
или нет.
Также см. " Запросы не обещания" в документации для мангуста.
Если вы используете mongoose, вы можете использовать .populate()
чтобы получить информацию о ваших storages
из коллекции Storage
.
можете попробовать это
module.exports.storageDetail = function(req, res) {
User.findOne({'userId': req.user.userId}, 'storages')
.populate('storages')
.exec(function (err, storageList) {
if (err) return handleError(err);
console.log(storageList);
res.render('storage_template', {
storage: storageList
});
});
}
для использования этого .populate()
убедитесь, что сначала в вашей модели User
вы добавили ref
для storages
лайк:
storages: [{ type: Schema.Types.ObjectId, ref: 'Storage' }]
//сделать npm установить lodash
const _ = require('lodash');
module.exports.storageDetail = function(req, res) {
User.findOne({'userId': req.user.userId}, 'storages').then(function(data){
var storageArray = [];
let queries = _.map(data.storages, (record)=>{
return Storage.findOne({_id: record}, function(err, storage){
storageArray.push(storage);
});
})
return Promise.all(queries);
}).then(function(storageList){
res.render('storage_template', {
storage: storageList
});
console.log(storageList);
});
}
.exec()
чтобы получить Обещание.