Есть способ решить эту проблему:
@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 варианта:
Используйте file = gridOperations.findOne(Query.query(Criteria.where("_id").is(id)));
InputStream is = file.getInputStream();
Взгляните на исходный код GridFSDBFile
. Здесь вы можете увидеть, как он внутренне запрашивает коллекцию fs.chunks
и заполняет InputStream.
(Вариант 2 действительно низкоуровневый, вариант 1 намного проще, и этот код поддерживается разработчиками MongoDB-Java-Driver, хотя вариант 1 был бы моим выбором).
Обновление записей GridFS:
- GridFS не предназначена для обновления содержимого файлов!
- Хотя может быть полезно только обновление поля
metadata
. Остальные поля немного статичны.
Вы должны иметь возможность просто использовать свой собственный метод MyGridFsFileRepo
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; }
}
И, конечно же, с каждым имплементом связан свой собственный AbstractMetadata
импл. Что я сделал? AbstractMetadata
всегда имеет поле с именем type
. Таким образом, я могу найти нужный AbstractMyGridFsFile
имп. Хотя у меня также есть общий абстрактный репозиторий.
Кстати: тем временем я перешел с Spring Repo на простой доступ через 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;
}
Надеюсь это поможет. Я могу написать больше, если вам понадобится дополнительная информация по этому поводу. Только скажи мне.
person
Benjamin M
schedule
05.08.2014