【问题标题】:Transfer image files from MongoDB to S3将图像文件从 MongoDB 传输到 S3
【发布时间】:2019-12-12 16:08:55
【问题描述】:

我有一个 NodeJS 应用程序,它将所有数据(甚至图像)存储到 MongoDB。现在我想使用 S3 来存储我的应用程序的文件(图像,43gb),所以我需要将我在 mongo 中的所有文件传输到那里。

我找到了可以将我的文件传输到 S3 实例(DigitalOcean 空间)的 s3cmd 工具,但我找不到实际访问这些文件的方法。我知道它们存储在fs.filesfs.chunks 集合中,但我不知道如何实际将它们用作s3cmd 的输入!

任何帮助将不胜感激!!!

编辑:这是存储图像的格式:

fs.files

{
  "_id" : ObjectId("5ae97922c1dabec8d2d0bdb0"),
  "filename" : "2b57455f3878d11dabc9c984da7de314_postImage.jpeg",
  "contentType" : "binary/octet-stream",
  "length" : 2291623,
  "chunkSize" : 261120,
  "uploadDate" : ISODate("2018-05-02T08:38:58.549Z"),
  "aliases" : null,
  "metadata" : null,
  "md5" : "9ad420eaa7c28a73e449199430627802"
}

fs.chunks.findOne()

{
  "_id" : ObjectId("5ae2d77f6616b4a9d93cb4b1"),
  "files_id" : ObjectId("5ae2d77f6616b4a9d93cb4b0"),
  "n" : 0,
  "data" : BinData(0,"iVBORw0KGgoAAAANSUhEUgAAAuAAAAJvCAYAAAA6OGQEAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABWWlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRher38tcAAAAASUVORK5CYII=") }

【问题讨论】:

  • 您是否尝试将存储在 MongoDB 中的二进制 blob 移动到 S3,或者磁盘上构成 MongoDB 数据库的实际文件(即默认情况下包含在 \data\db 中的文件) ?您可以将数据目录从一个 MongoDB 安装复制到另一个。因此,只需上传文件就足够了。也许我误解了你的问题。
  • 我想要的只是从我的 mongo 中获取图像并将它们传输到 S3。我知道 mongo 中的图像是按块存储的,所以我猜是二进制 blob?
  • 除非 S3 的某些功能允许它访问您的 MongoDB 并提取字节数组,否则我认为您必须以编程方式执行此操作。我不知道有什么方法可以让 MongoDB 服务器将文档推送到非 mongoDB 目标。
  • 好的!然后以编程方式!你知道怎么做吗?
  • 我想您会使用 NodeJS 驱动程序来提取数据并通过 S3 SDK aws.amazon.com/sdk-for-node-js 将其推送到 S3

标签: mongodb amazon-s3 digital-ocean gridfs s3cmd


【解决方案1】:

所以,基本上你可以做的是创建一个Writable Stream,你必须在其中访问数据库以读取所有文档,并且在 write 方法中,你要将文件上传到 AWS S3,并且可能稍后使用返回的信息更新 mongodb 文档。

一个例子可以是:

// uploadFile.js
const AWS = require("aws-sdk");

const BUCKET_NAME = 'my-bucket';
const S3 = new AWS.S3();

// This function will upload the file to AWS S3 in the defined bucket 
const uploadFile = (Body, Key, opts = {}) =>
 S3.upload(
      {
        Bucket: BUCKET_NAME,
        Key,
        Body,
        ...opts
      }
  ).promise();
// migrate.js

const client = require("../mongo-client");
const { Writable, pipeline } = require("stream");
const util = require("util");


const pipe = util.promisify(pipeline);

// this will get all the documents that are going to be migrated
const getDocuments = () =>
  client.withCollection("chunks").then(({ collection }) =>
    collection
      .find({});

// this method will update the document after the file has been uploaded to AWS S3 with
// the s3 path and version 
const updateDocument = ({ _id }) => (response) => client.withCollection("chunks")
  .then(collection => collection.update({ _id }, {$set: {awsPath: response}, $unset: ["file"] }));

// This is the writable that's going to upload and later update the document in the db
class TransferWritable extends Writable {
  _write(doc, encoding, callback) {
     uploadFile(doc._id, doc.data.buffer)
       .then(updateDocument(doc))
       .then(callback)
       .catch(callback);
  }
}


const migrate = getDocuments
  .then(stream => pipe(stream, new TransferWritable({ objectMode: true })))
  .catch(console.error)

【讨论】:

    【解决方案2】:

    您需要分两步完成:看看here

    1. 从 mongodb 导出数据(document-wise/collection-wise/completeDB)。

    mongoexport --host [localhost] --db [db-name] --collection [集合名称] --out [输出文件.json]

    1. 将导出的数据导入服务器上的mongodb。

    mongoimport --host [s3-server-host] --db [db-name] --collection [集合名称] --file [input-file.json]

    [如果对您有帮助,请投票给这个答案]

    【讨论】:

    • 但这将导出我的数据库的集合。我想要的是导出我的数据库文件并将它们存储到 S3(对象存储)
    • 那么下面的链接可能会对您有所帮助。 1.codeproject.com/Tips/547759/… 2.digitalocean.com/community/tutorials/…
    • 我没有关于如何导出集合的问题,也没有关于如何将其发送到 S3 的问题。我遇到的问题是如何导出实际文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-16
    • 2014-10-24
    • 1970-01-01
    • 2011-11-10
    • 1970-01-01
    • 2019-01-08
    • 2011-11-10
    相关资源
    最近更新 更多