繁体   English   中英

Node.js / MongoDB / Mongoose:缓冲区比较

[英]Node.js / MongoDB / Mongoose: Buffer Comparison

首先,一点背景:

我正在尝试检查图像的二进制数据是否已经保存在Mongo中。 给定以下架构:

var mongoose = require('mongoose')
  , Schema = mongoose.Schema;

var imageSchema = new Schema({
    mime:  String,
    bin: { type: Buffer, index: { unique: true }},
    uses : [{type: Schema.Types.ObjectId}]
});

module.exports = mongoose.model('Image', imageSchema);

...我想查询是否存在图像,是否添加了我的对象正在使用它的引用,然后更新它。 如果没有,我想创建(upsert)它。

鉴于它不存在的情况,下面的代码完美地工作。 如果是,则以下代码不会,并将另一个Image文档添加到Mongo。 我觉得它可能是Mongo Buffer类型与节点缓冲区的比较问题,但我无法弄清楚如何正确地比较它们。 请让我知道如何更新以下内容! 谢谢!

Image.findOneAndUpdate({
    mime : contentType,
    bin : image
}, {
    $pushAll : {
        uses : [ myObject._id ]
    }
}, {
    upsert : true
}, function(err, image) {
    if (err)
        console.log(err);
    // !!!image is created always, never updated!!!
});

Mongoose将目标存储的缓冲区元素转换为mongodb Binary ,但在执行查询时会执行适当的强制转换。 单元测试中也检查了预期的行为(也是node.js Buffer的存储和检索)。

你确定要传递node.js缓冲区吗?

在任何情况下,我认为处理初始问题的最佳方法(检查图像是否已经在数据库中)将存储二进制数据的强哈希摘要(sha1,sha256,...)并检查(使用加密模块)。 查询时,作为初步测试,您还可以检查二进制长度以避免不必要的计算。

有关如何在存储/查询图像之前获取图像摘要的示例:

var crypto = require('crypto');

...

// be sure image is a node.js Buffer
var image_digest = crypto.createHash('sha256');
image_digest.update(image);
image_digest = image_digest.digest('base64');

通过node.js查询包含图像数据的缓冲区来查询图像不是一个好主意。 你是对的,它可能是BSON二进制数据类型和节点Buffer之间的问题,但你的应用程序真的需要这样的比较吗?

相反,我会在您的架构中添加一个imageID或slug字段,在此字段中添加索引,并在findOneAndUpdate调用中对其进行查询而不是bin

var imageSchema = new Schema({
    imageID: { type: String, index: { unique: true }},
    mime:  String,
    bin: Buffer,
    uses : [{type: Schema.Types.ObjectId}]
});

哈希确实有效,我使用的另一个过滤器是图像的exif数据。 由于这是结构化信息,如果您在exif数据上匹配,则可以进入下一步检查哈希或文件大小的匹配...

大量的节点模块可以很好地为您的存储获取exif数据:)示例代码获取节点的exif数据

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM