1

我最近从关系数据库切换到了 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 都将始终有效。

4

1 回答 1

0

我看到您找到了一个解决方案,即_id使用 MongoDb 驱动程序的ObjectID()功能在保存之前指定一个。但是,这里有几个其他选项,因为驱动程序当前不支持返回对象或_id插入后...

您可以立即为您的input对象查询数据库,因为它可以保证匹配,如下所示:

collection.find(input, function (err, savedImage) {
  // use savedImage._id here...
}

这样做的缺点是查询可能匹配多个文档(取决于您插入的数据)。如果是这种情况,您始终可以按时间戳排序并限制为 1 个文档(提示:实际上所有 ObjectId 中都嵌入了时间戳)。

您在问题中暗示的另一个解决方案是在多个集合中使用嵌入而不是引用。这可能是一个更好的解决方案,并且更好地遵循了无模式设计的理念。嵌入可能也会更快。但是重新设计您的应用程序以使其工作可能更难。

于 2013-11-08T19:14:47.247 回答