我对MongoDB存在概念性问题,最近从关系数据库切换。
我试图用以下内容存储图像:
exports.save = function ( input, image, callback) {
console.log('Image Provider, trying to handle image ...');
input.date = new Date();
if (input._id) {
input._id = new ObjectID(input._id);
}
console.log("image is " + image + " image size is " + image.size);
if (image && image.size) {
var data = fs.readFileSync(image.path);
input.image = new MongoDb.Binary(data);
input.imageType = image.headers['content-type'];
input.imageName = image.name;
console.log("input is " + input);
}
db.collection("images", function (error, collection) {
collection.save(input, {safe: true}, callback);
});
};
这称为如下:
ImageProvider.save(input, function(err, objects) {
input.image_id = objects._id;
console.log('[inside] objects id is ' + input.image_id);
if (err) {
// do something
} else {
// do something else
}
});
我想在另一个集合中使用图像_id,基本上它会在图像集合中插入对此图像对象的引用。由于异步调用,当我将下一个对象插入另一个集合时,_id尚不可用。
是否有用于插入对另一个集合对象的引用的标准模式或者是 简单地将整个(其他对象)插入同一个集合中的最佳方法是什么?
我找到了一个解决方案/策略,它基本上是在调用SAVE函数之前创建ObjectID
类似的东西:
ObjectID = MongoDb.ObjectID;
input._id = new ObjectID();
然后保存输入。在这种情况下,无论异步调用返回多长时间,_id始终有效。
答案 0 :(得分:0)
我发现你找到了一个解决方案,即在使用MongoDb驱动程序的_id
函数进行保存之前指定ObjectID()
。但是,这里有几个其他选项,因为驱动程序当前不支持在插入后返回对象或_id
...
您可以立即在数据库中查询您的input
对象,因为它保证匹配,如下所示:
collection.find(input, function (err, savedImage) {
// use savedImage._id here...
}
这样做的缺点是查询可能匹配多个文档(取决于您插入的数据)。如果是这种情况,您可以随时对时间戳进行排序并限制为1个文档(提示:实际上所有ObjectIds中都嵌入了时间戳)。
您在问题中暗示的另一个解决方案是在多个集合中使用嵌入而不是引用。这可能是一个更好的解决方案,并且更好地遵循无架构设计的理念。嵌入可能也会更快。但是重新设计应用程序以使其工作可能更难。