16

我最近发现了 GridFS,我想将它用于带有元数据的文件存储。我只是想知道是否可以使用 aMongoRepository来查询 GridFS?如果是,有人可以举个例子吗?

如果有的话,我也会采用 Hibernate 的解决方案。

new Query(Criteria.where(...))原因是:我的元数据包含许多不同的字段,查询存储库比为每个场景编写一些更容易。我希望也可以简单地获取一个 Java 对象并通过 REST API 提供它,而不需要文件本身。

编辑:我正在使用

  • 春季 4 测试版
  • Spring Data Mongo 1.3.1
  • 休眠 4.3 测试版
4

2 回答 2

15

有一种方法可以解决这个问题:

@Document(collection="fs.files")
public class MyGridFsFile {

    @Id
    private ObjectId id;
    public ObjectId getId() { return id; }

    private String filename;
    public String getFilename() { return filename; }

    private long length;
    public long getLength() { return length; }

    ...

}

你可以为此编写一个普通的 Spring Mongo Repo。现在您至少可以fs.files使用 Spring Data Repo 查询集合。但是:您不能以这种方式访问​​文件内容。

为了获取文件内容本身,您有(至少)2个选项:

  1. 采用file = gridOperations.findOne(Query.query(Criteria.where("_id").is(id))); InputStream is = file.getInputStream();

  2. 看看源代码GridFSDBFile。在那里您可以看到它如何在内部查询fs.chunks集合并填充 InputStream。

(选项 2 非常低级,选项 1 更容易,并且此代码由 MongoDB-Java-Driver 开发人员维护,尽管选项 1 是我的选择)。


更新 GridFS 条目:

  • GridFS不是为更新文件内容而设计的!
  • 尽管仅更新metadata字段可能很有用。其余字段有点静态。

您应该能够简单地使用您的 customMyGridFsFileRepo方法update。我建议为该metadata字段创建一个设置器。


不同文件的不同元数据:

我使用abstract MyGridFsFile具有通用元数据的类解决了这个问题,即:

@Document(collection="fs.files")
public abstract class AbstractMyGridFsFile<M extends AbstractMetadata> {

    ...

    private M metadata;
    public M getMetadata() { return metadata; }
    void setMetadata(M metadata) { this.metadata = metadata; }

}

当然,每个 impl 都有自己AbstractMetadata关联的 impl。我做了什么?AbstractMetadata总是有一个字段叫做type. 这样我就可以找到正确的AbstractMyGridFsFileimpl。虽然我也有一个通用的抽象存储库。

顺便说一句:与此同时,我从使用 Spring Repo 切换到使用普通访问 via MongoTemplate,例如:

protected List<A> findAll(Collection<ObjectId> ids) {
    List<A> files = mongoTemplate.find(Query.query(Criteria
            .where("_id").in(ids)
            .and("metadata.type").is(type) // this is hardcoded for each repo impl
    ), typeClass); // this is the corresponding impl of AbstractMyGridFsFile
    return files;
}

希望这可以帮助。如果您需要有关此的更多信息,我可以写更多。就告诉我嘛。

于 2014-08-05T12:43:31.007 回答
2

您可以使用 MongoTemplate 中的数据库创建一个 GridFS 对象,然后与之交互:

MongoTemplate mongoTemplate = new MongoTemplate(new Mongo(), "GetTheTemplateFromSomewhere");
GridFS gridFS = new GridFS(mongoTemplate.getDb());

GridFS 对象允许您创建、删除和查找等。

于 2013-10-24T14:39:26.293 回答