使用模式方法在 Mongoose For 循环中保存项目
Posted
技术标签:
【中文标题】使用模式方法在 Mongoose For 循环中保存项目【英文标题】:Saving Items In Mongoose For Loop With Schema Methods 【发布时间】:2015-02-12 13:25:16 【问题描述】:如果我附加任何额外的验证方法,我会在保存通过 for 循环运行的项目时遇到问题。基本上,我正在构建一个 instagram API 应用程序,它允许编辑者删除不合时宜的照片。照片分批从 Instagram 中提取 20 张并显示给编辑。如果编辑者点击一张照片,它首先会按 ID 被放入“黑名单”数据库,然后从主照片数据库中删除。
为了不让列入黑名单的照片重新出现在提要中,在将项目保存到主照片数据库之前,它需要根据黑名单检查照片的 Instagram ID。为此,我使用了 Schema 方法。
现在的问题是,我只能将一张照片保存到数据库中。如果我取出方法检查,那么我得到了全部 20 个。
这是我的主要创建控制器:
exports.create = function(req, res)
var topic = req.body.topic || 'nyc';
var path = 'https://api.instagram.com/v1/tags/' + topic + '/media/recent?client_id=' + 'XXXXXXXXXX';
request.get(url: path, function(err, response)
if (err)
console.log('Failed to get data: ', err);
return res.status(400).json(error: 'Not allowed');
else
// ------------------------------------------------
// Make sure we have JSON
//
var body = JSON.parse(response.body);
// ------------------------------------------------
// Loop through each response
//
for (var i = 0; i < body.data.length; i++ )
var photoData = body.data[i];
// ------------------------------------------------
// If there is no caption, skip it
//
if (!photoData.caption)
text = '';
else
text = photoData.caption;
// ------------------------------------------------
// Create new photo object
//
var photo = new Photo(
link: photoData.link,
username: photoData.user.username,
profilePicture: photoData.user.profile_picture,
imageThumbnail: photoData.images.thumbnail.url,
imageFullsize: photoData.images.standard_resolution.url,
caption: text,
userId: photoData.user.id,
date: photoData.created_time,
_id: photoData.id
);
photo.checkBlacklist(function(err, blacklist)
if (!blacklist)
photo.save(function(err, item)
if (err)
console.log(err);
console.log('Saved', item);
)
);
// -------------------------------------------------
//
// Save
//
// -------------------------------------------------
// END FOR LOOP
console.log('Photos saved');
return res.json(201, msg: 'Photos updated' );
);
;
这是我的照片架构:
'use strict';
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var Blacklist = require('../blacklist/blacklist.model');
var PhotoSchema = new Schema(
created: type: Date, default: Date.now(),
date: String,
link: String,
username: String,
profilePicture: String,
imageThumbnail: type: String, unique: true,
imageFullsize: String,
caption: String,
userId: String,
_id: type: String, unique: true
);
PhotoSchema.methods.checkBlacklist = function(callback)
return Blacklist.findById(this._id, callback);
;
module.exports = mongoose.model('Photo', PhotoSchema);
奇怪的是,我在创建控制器中收到了所有 20 次保存的控制台消息: console.log('已保存', item);
但实际上只保存了一张照片。任何想法为什么?
谢谢
【问题讨论】:
当您必须对数组中的项目执行相同的异步任务时,不要使用常规的for
循环。查看async.each
,它更适合您的场景。
对此一无所知。立即完美运行。也许提供答案,以便我可以标记它?非常感谢
【参考方案1】:
当您必须对数组中的项目执行相同的异步任务时,不要使用常规的 for 循环。查看async.each,它更适合您的场景,例如(只是代码的else
部分):
var body = JSON.parse(response.body);
async.each(body.data, function (photoData, callback)
// ------------------------------------------------
// If there is no caption, skip it
//
if (!photoData.caption)
text = '';
else
text = photoData.caption;
// ------------------------------------------------
// Create new photo object
//
var photo = new Photo(
link: photoData.link,
username: photoData.user.username,
profilePicture: photoData.user.profile_picture,
imageThumbnail: photoData.images.thumbnail.url,
imageFullsize: photoData.images.standard_resolution.url,
caption: text,
userId: photoData.user.id,
date: photoData.created_time,
_id: photoData.id
);
photo.checkBlacklist(function(err, blacklist)
if (!blacklist)
photo.save(function(err, item)
if (err)
console.log(err);
console.log('Saved', item);
callback();
);
);
, function (error)
if (error) res.json(500, error: error);
console.log('Photos saved');
return res.json(201, msg: 'Photos updated' );
);
别忘了安装
npm install async
并要求async
:
var async = require('async');
【讨论】:
我认为您将获得与列表长度成正比的堆栈深度是否正确?即它递归到回调,然后再次每个函数? 根据文档 - 是的,除非您明确推迟回调以便它在另一个滴答声中运行:“出于性能原因,异步不会防止同步迭代。如果您仍然遇到堆栈溢出,您可以按照上面的建议推迟,或者用 async.ensureAsync 包装函数“caolan.github.io/async 这是唯一有效的答案,但它让我心烦意乱,这么明显的问题怎么可能没有在猫鼬中开箱即用的解决方案。无论如何,谢谢罗德里戈!【参考方案2】:递归求解如何
saveGames = (depth) =>
if (depth > 0)
var newGame = new Game( user: user._id );
newGame.save((err, game) =>
if (err)
console.log(err);
return res.status(203).json(
title: 'error',
error: message: 'Error Saving Games'
);
user.games.push(game);
user.save((err, user) =>
if (err)
console.log(err);
return res.status(203).json(
title: 'error',
error: message: 'Error Saving Games'
);
saveGames(depth - 1);
);
);
saveGames(5);
【讨论】:
以上是关于使用模式方法在 Mongoose For 循环中保存项目的主要内容,如果未能解决你的问题,请参考以下文章
如何在 mongoose 中使用 update many 来循环遍历 8 个元素并将它们放入该模式中的数组中