【问题标题】:MongoDB save images in user collection with GridfsMongoDB 使用 Gridfs 将图像保存在用户集合中
【发布时间】:2015-03-17 11:41:04
【问题描述】:

目前我正在使用 Scala 开发带有 Play 2 Framework 的后端服务器。 我有以下问题:

我使用文件处理程序 GridFS 在 MongoDB 中保存图像等文档。 GridFs 创建两个文件:

fs.files,其中包含元数据和 fs.chunks,存储块

但我想将图像保存在我自己的收藏中。所有图像都应该有一个数据库条目,如用户名和 cmets。 我有两个想法如何解决这个问题,但我需要帮助。

解决方案 #1:

使用我自己的收藏:

{
   username: String
   comments: Array<String>
   image   : Gridfs 
}

如何使用 GridFS 在我自己的集合中获取图像?有可能吗?

解决方案 #2:

我使用 fs.files 集合,其中包含元数据并添加条目用户名和 cmets。我试过了,还是不行。

谁能帮助我?

谢谢

【问题讨论】:

  • 您的图像文件大小有多大? GridFS 是存储非常大文件的有用方法,但如果您的图像小于maximum document size(在 MongoDB 2.6 为 16MB),则不是必需的。您可以考虑将图像作为二进制数据直接存储在文档中(这听起来更接近您建议的解决方案所追求的)。
  • 我还不能说。因为我也想存储音频和视频文件。这就是我想使用gridfs的原因。视频文件将超过 16MB

标签: mongodb scala collections playframework gridfs


【解决方案1】:

至于解决方案#1

如果你使用 ReactiveMongo,有一个示例项目,具有复合服务器响应,由文件和 json 组成

https://github.com/sgodbillon/reactivemongo-demo-app/blob/master/app/controllers/Application.scala

 def showEditForm(id: String) = Action.async {
    val objectId = new BSONObjectID(id)
    // get the documents having this id (there will be 0 or 1 result)
    val futureArticle = collection.find(BSONDocument("_id" -> objectId)).one[Article]
    // ... so we get optionally the matching article, if any
    // let's use for-comprehensions to compose futures (see http://doc.akka.io/docs/akka/2.0.3/scala/futures.html#For_Comprehensions for more information)
    for {
      // get a future option of article
      maybeArticle <- futureArticle
      // if there is some article, return a future of result with the article and its attachments
      result <- maybeArticle.map { article =>
        import reactivemongo.api.gridfs.Implicits.DefaultReadFileReader
        // search for the matching attachments
        // find(...).toList returns a future list of documents (here, a future list of ReadFileEntry)
        gridFS.find(BSONDocument("article" -> article.id.get)).collect[List]().map { files =>
          val filesWithId = files.map { file =>
            file.id.asInstanceOf[BSONObjectID].stringify -> file
          }
          Ok(views.html.editArticle(Some(id), Article.form.fill(article), Some(filesWithId)))
        }
      }.getOrElse(Future(NotFound))
    } yield result
  }

您可以将其用作参考实现。

至于解决方案#2

您应该能够在 DefaultFileToSave.metadata 中存储其他数据,然后使用 { "metadata.user" : "user"} 查询 mongo(查看 Query on MongoDB GridFS metadata (Java)

另一种解决方案

将文件和您的元信息保持为独立实体,并独立管理它们,将来扩展它们会更容易。

对于 GridFS 上传功能 (https://github.com/ReactiveMongo/Play-ReactiveMongo)

def upload = Action(gridFSBodyParser(gridFS)) { request =>
  // here is the future file!
  val futureFile: Future[ReadFile[BSONValue]] = request.body.files.head.ref
  futureFile.map { file =>
    // do something
    Ok
  }.recover {
    case e: Throwable => InternalServerError(e.getMessage)
  }
}

以端点为例,在前面的基础上进行扩展

  • /video/:id/file - 您的 GridFS 文件端点
  • /video/:id/meta - 您的元信息端点(无论您需要什么)
  • /video/:id(可选)- 组合文件和元响应。

【讨论】:

  • 感谢您的回答。我正在将 Play-ReactiveMongo 与 casbah 一起使用。我找不到存储图像的位置?据我所知,在 MongoDB 中不支持连接。如何将文件和元信息保存为独立实体?你能给我一些例子吗?
猜你喜欢
  • 2012-11-15
  • 2021-11-08
  • 2014-05-11
  • 1970-01-01
  • 1970-01-01
  • 2020-12-07
  • 2012-02-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多