2014-11-07 4 views
3

В настоящее время существует требование, что есть объект - «приложение», в котором есть: «имя», «uploadTime» и «executeFile».Ссылка на файл Mongo document и gridfs

В настоящее время база данных является mongodb. Я хочу использовать документ

Class Application { 
    String id; 
    String name; 
    String type; 
    Date uploadTime; 
    GridFSDBFile executeFile; 
} 

дао слой, когда я пишу сохранить, я нахожу, что я не могу связанные GridFSDBfile непосредственно документа. Мне нужно сначала использовать GridFsTemplate.store сохранить GridDBFile, а затем использовать GridFsTemplate.findOne найти его по имени и поместить объект вложенный в документ приложения. Затем используйте MongoOperation, чтобы сохранить документ приложения.

try { 
     inputStream = new FileInputStream("C:/testing.app"); 
     gridFsOperations.store(inputStream, "test.app", "jar"); 

    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } finally { 
     if (inputStream != null) { 
      try { 
       inputStream.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    Query query = query(where("filename").is("test.app")); 
    GridFSDBFile gridFsDBFile = gridFsOperations.findOne(query); 

    Application application = new Application(); 
    application.setName("test-app"); 
    application.setType("type", "Java"); 
    application.setexecuteFile (gridFsDBFile); 

    applicationDao.save(application); 

Есть ли способ позвонить в MongoOperation? Если нет, я думаю, что вызов GridFsTemplate.store и MongoOperation.save необходимо выполнить в транзакции. Я помню, что Монго не поддерживал транзакцию. Как это сделать? Проверять транзакцию только в Java-коде?

ответ

1

Я нахожу, что не могу связать GridFSDBfile с документом напрямую. Мне нужно сначала использовать GridFsTemplate.store сохранить GridDBFile, а затем использовать GridFsTemplate.findOne найти его по имени и поместить объект вложенный в документ приложения. Затем используйте MongoOperation, чтобы сохранить приложение .

Вы здесь ошибаетесь. Когда вы сохраняете файл в GridFS, хранилище файла и его метаданные распределяются между двумя коллекциями, а именно: fs.files и fs.chunks. Всякий раз, когда файл вставляется с помощью GridFs API, файл и его метаданные сохраняются одним выстрелом.

Чтобы дать более полную картину,

Когда ниже инструкция выполняется:

gridFsOperations.store(inputStream, "test.app", "jar"); 

MongoDB делает две записи, один в fs.files, а другой к fs.chunks коллекций.

одна запись сделана в fs.files коллекции:

{ 
     "_id" : ObjectId("545d6699756c779b8cb8b13d"), 
     "type":"jar", 
     "filename" : "test.app", 
     "aliases" : null, 
     "chunkSize" : NumberLong(262144), 
     "uploadDate" : ISODate("2014-11-08T00:40:57.298Z"), 
     "length" : NumberLong(433), 
     "contentType" : null, 
     "md5" : "5e49ad0614687c7ad343f6f9fe6843b2" 
} 

Эта запись содержит только информацию о метаданных файла, например, имя файла и тип. Вы даже можете установить другую информацию метаданных, используя класс BasicDBObject. Вы хотите включить uploadTime,

DBObject metadata = new BasicDBObject(); 
metadata.put("uploadTime", Calendar.getInstance().getTime()); 

и сохранить его, как показано ниже,

gridFsOperations.store(inputStream, "test.app", "jar",metadata); 

Также он имеет одну часть важной информации, то есть ссылка на документ, который содержит фактическое содержимое файла, в его _id поле.

Другая запись сделана в fs.chunks коллекции:

{ 
     "_id" : ObjectId("545d6699756c779b8cb8b13e"), 
     "files_id" : ObjectId("545d6699756c779b8cb8b13d"), 
     "n" : 0, 
     "data" : BinData(0,"PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4N 
Cjx4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5z 
Zm9ybSINCnZlcnNpb249IjEuMCI+DQoNCjx4c2w6b3V0cHV0IGVuY29kaW5nPSJVVEYtOCIgbWV0aG9k 
PSJ4bWwiIGluZGVudD0ieWVzIi8+DQo8eHNsOnZhcmlhYmxlIG5hbWU9InRvcExldmVsIj4NCiAgICAg 
ICAgPHhzbDp2YXJpYWJsZSBuYW1lPSJpbm5lciIgc2VsZWN0PSInSGknIiAvPg0KICAgICAgICA8eHNs 
OnZhbHVlLW9mIHNlbGVjdD0iJGlubmVyIi8+DQo8L3hzbDp2YXJpYWJsZT4NCiAgICANCjx4c2w6dGVt 
cGxhdGUgbWF0Y2g9Ii8iID4NCiAgICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0iJHRvcExldmVsIiAvPg0K 
PC94c2w6dGVtcGxhdGU+DQo8L3hzbDpzdHlsZXNoZWV0Pg==") 
} 

Это реальный документ, который содержит содержимое файла в его Binary форме. Обратите внимание на поле документа files_id. Он имеет то же самое ObjectId, как указано в записи в коллекции fs.files.

Так как MongoDB поддерживает связь между содержимым файла и его метаданными. GridFS - простой API, позволяющий абстрагировать пользователя от обработки низкого уровня.

f нет, я думаю, что вызов GridFsTemplate.store и MongoOperation.save необходимо выполнить в транзакции. Я помню, что Mongo doens't не поддерживает транзакции . Как это сделать? Проверять транзакцию только в Java-коде?

Приложение не нуждается в создании или обслуживании каких-либо транзакций для этой операции.

+0

Я думаю, вы можете неправильно понять мою точку зрения. мой вопрос заключается не в содержании файла и метаданных файлов. Мой вопрос: у меня нормальный документ, и этот нормальный документ имеет элемент gridfs. Я хочу сохранить документ и каскадировать, сохраняя элемент gridfs. Или я должен сначала сохранить элемент gridfs, а затем сохранить документ вручную. Вы знаете, как каскадировать сохранение? – user3003466

+0

Вот где вы ошибаетесь. Вы всегда можете запросить коллекцию fs.chunks для файла. Нет смысла хранить содержимое снова в другой коллекции. Вам нужно пересмотреть свой подход. – BatScream

+0

@BatScream привет, пожалуйста, вы можете сказать, каким будет оптимизированный способ управления данными, подобным этому: Пользователь, file.files и file.chunks - это три коллекции, я хочу, чтобы конкретный пользователь со всем связанным с ним файлом в ответ был возможное.? { "имя": "Batman", «электронная почта»: "[email protected]", "файлы": [{ file1}, {file2}, {file3}, .... так далее ] } –

Смежные вопросы