我正在尝试使用GridFS在mongo DB中存储版本化内容。因此,我将一个版本字段添加到我正在存储的文件的元数据中。这一切都运作良好。现在我想在不知道版本的情况下获得最新版本。这里:Find the latest version of a document stored in MongoDB - GridFs有人提到,如果匹配查询,findOne总是返回最年轻(最新)的文件。什么是我想要的。但是当我尝试这个时,我总是从findOne()获得第一个(最旧的)文件。我正在使用spring-data-mongodb
版本1.5.0.RELEASE
这是我目前的代码:
public void storeFileToGridFs(ContentReference contentReference, InputStream content) {
Integer nextVersion = findLatestVersion(contentReference) + 1;
DBObject metadata = new BasicDBObject();
metadata.put("version", nextVersion);
metadata.put("definitionId", contentReference.getContentDefinitionId());
gridOperations.store(content, contentReference.getContentId().getValue(), metadata);
}
并找到最新版本:
private Integer findLatestVersion(ContentReference contentReference) {
Query query = new Query(GridFsCriteria.whereFilename().is(contentReference.getContentId().getValue()));
GridFSDBFile latestVersionRecord = gridOperations.findOne(query);
if (latestVersionRecord != null) {
Integer version = (Integer) latestVersionRecord.getMetaData().get("version");
return version;
} else return 0;
}
但是,正如已经提到的,findLatestVersion()总是返回1(第一次,当它返回0时...
如果我有这个运行,有没有办法只检索文档的元数据?在findLatestVersion()
中,没有必要加载文件本身。
答案 0 :(得分:1)
findOne
只返回一个结果,更具体地说是与查询匹配的 first 一个结果。
我不太确定使用findOne时是否返回了最新版本。请尝试查找。
更加手动的方法是过滤结果集,查询最高版本值的文件名。
通常,版本字段仅显示文档更改的频率。它用于称为乐观锁定的东西,它通过检查文档的当前版本与更改的文档所具有的版本来工作。如果数据库中的版本高于要保存的文档中的版本,则另一个进程对文档进行了更改,并引发异常。
对于存储版本化文档,git(例如通过egit)可能是一种解决方案。
编辑:经过快速研究,以下是它的工作原理。应使用元数据中自动设置的上载日期完成文件版本控制。查询它,降序排序并使用第一个结果。您无需再手动设置版本。
答案 1 :(得分:0)
尝试向查询添加排序,如下所示:
GridFSDBFile latestVersionRecord = template.findOne(
new Query(GridFsCriteria.whereFilename().is(filename))
.with(new Sort(Sort.Direction.DESC, "version")));
一旦有了GridFSDBFile,就可以轻松检索元数据,而无需使用以下方法加载整个文件:
DBObject metadata = latestVersionRecord.getMetaData();
希望它有所帮助!
答案 2 :(得分:0)
我知道已经有一段时间了,因为这个问题已被提出,我不知道当时的代码是否相同,但我认为这些信息可能有助于未来的读者:
查看源代码会显示findOne completely ignores the sorting part defined in the query,而find actually makes use of it。
因此,您需要使用find进行常规查询,然后选择找到的第一个对象(有关详细信息,请参阅Markus W Mahlberg's answer)。