我正在开发一个使用mongodb的插件。该插件必须将一些.dcm文件(DICOM文件)作为二进制文件存储在数据库中。之后,插件必须存储文件的元数据,并且只能对这些元数据进行一些查询。
当然,我选择了GridF来回答我的问题。因为我可以使用相同的文件将二进制数据存储在块集合中,并将元数据存储在文件集合的元数据字段中(并绕过MongoDB的大小限制)。
但另一个问题出现在我面前。这个解决方案很棒,但我同时存储二进制数据和元数据。让我解释一下:首先我存储二进制文件,之后我检索文件并从中读取元数据并将元数据存储在同一个文件中。出于某些外部原因,这是我的责任。所以我失去了很多时间来检索文件并再次恢复它。要更新已存储的文件中的元数据,我使用以下代码:
GridFSDBFile file = saveFs.findOne(uri.getFileName());
if (file == null) {
return false;
} else {
file.setMetaData(new BasicDBObject());
file.save();
return true;
}
主要的问题是我必须先找到该文件才能修改它然后再将它存储起来!
所以我的第一个问题是:有没有最好的方法从数据库中检索文件而不是findOne(String fileName)?方法findOne(ObjectID id)是否更快? (我不这么认为,因为我认为fileName默认已编入索引,不是吗?)
我尝试过另一种方法。为了绕过这个问题,我决定存储2个不同的文件,一个用于二进制数据,一个用于元数据。在这种情况下,我没有时间在数据库中检索文件。但是我的文件数量增加了2倍......但我几乎可以肯定它存在更好的方法!
所以我的第二个问题:你认为我必须使用2个不同的收藏品吗?一个使用GridF存储二进制数据,另一个使用经典的mongo存储(或GridFS)来存储元数据?
非常感谢你阅读我和你的答案:)。
答案 0 :(得分:1)
对于您的第一个问题,默认情况下,_id和filename字段都会被编入索引。虽然_id字段是唯一的,但文件名不是。因此,如果您的文件具有相同的文件名,则获取具有文件名的文件将比通过_id字段获取文件相对慢。
对于第二个问题,您始终可以为您插入的任何GirdFS文件提供元数据。这意味着您不必拥有超过GridFS。使用GridFS插入数据,但在插入数据之前,将元数据分配给要插入的文件。这样您就可以使用元数据查询文件。如果您想拥有的元数据对于所有文档都是固定的,那么您可以将这些字段编入索引,当然也可以查询。