Ответ 1
Есть способ решить эту проблему:
@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; }
}
И, конечно же, каждый impl имеет собственный AbstractMetadata
impl. Что я сделал? AbstractMetadata
всегда имеет поле, называемое type
. Таким образом, я могу найти правильный AbstractMyGridFsFile
impl. Хотя у меня также есть общий абстрактный репозиторий.
Btw: Тем временем я переключился сюда с помощью 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;
}
Надеюсь, это поможет. Я могу написать больше, если вам нужна дополнительная информация об этом. Просто скажи мне.