복붙노트

[MONGODB] 유성 : GridFS 대 파일 시스템 대 몽고의 컬렉션에 클라이언트에서 업로드 파일

MONGODB

유성 : GridFS 대 파일 시스템 대 몽고의 컬렉션에 클라이언트에서 업로드 파일

유성은 훌륭하지만 기존의 파일 업로드에 대한 네이티브 지원이 부족하다. 핸들 파일 업로드에 대한 몇 가지 옵션이 있습니다 :

클라이언트에서 데이터를 사용하여 전송 될 수있다 :

서버에서 파일을 저장할 수 있습니다 :

이러한 방법과 최선의 방법을 구현하는 방법에 대한 장점과 단점은 무엇입니까? 나는이 같은 타사 사이트에 저장과 같은 다른 옵션도하고 URL을 얻을 수 있음을 알고 있습니다.

해결법

  1. ==============================

    1.당신은 더 이상 패키지 또는 제 3자를 사용하지 않고 유성와 파일 업로드를 얻을 수 있습니다

    당신은 더 이상 패키지 또는 제 3자를 사용하지 않고 유성와 파일 업로드를 얻을 수 있습니다

    /*** client.js ***/
    
    // asign a change event into input tag
    'change input' : function(event,template){ 
        var file = event.target.files[0]; //assuming 1 file only
        if (!file) return;
    
        var reader = new FileReader(); //create a reader according to HTML5 File API
    
        reader.onload = function(event){          
          var buffer = new Uint8Array(reader.result) // convert to binary
          Meteor.call('saveFile', buffer);
        }
    
        reader.readAsArrayBuffer(file); //read the file as arraybuffer
    }
    
    /*** server.js ***/ 
    
    Files = new Mongo.Collection('files');
    
    Meteor.methods({
        'saveFile': function(buffer){
            Files.insert({data:buffer})         
        }   
    });
    

    설명

    첫째, 파일은 HTML5 파일 API를 사용하여 입력에서 잡고있다. 독자는 새로운을 FileReader을 사용하여 생성된다. 이 파일은 readAsArrayBuffer로 읽습니다. 당신이 CONSOLE.LOG 경우가 Uint8Array로 변환해야합니다 있도록이 arraybuffer는 반환 {}과 DDP는 와이어를 통해이를 보낼 수 없습니다.

    당신이 Meteor.call에 넣고 때, 유성은 자동으로 EJSON.stringify (Uint8Array)를 실행하고 DDP로 전송합니다. 당신은 크롬 콘솔 웹 소켓 트래픽의 데이터를 확인하실 수 있습니다, 당신은 문자열을 base64를 닮은 볼 수 있습니다

    그것은 백 버퍼 서버 측에서 유성 호출 EJSON.parse () 및 변환

    프로

    단점

    /*** client.js ***/
    
    // asign a change event into input tag
    'change input' : function(event,template){ 
        var file = event.target.files[0]; 
        if (!file) return;      
    
        var xhr = new XMLHttpRequest(); 
        xhr.open('POST', '/uploadSomeWhere', true);
        xhr.onload = function(event){...}
    
        xhr.send(file); 
    }
    
    /*** server.js ***/ 
    
    var fs = Npm.require('fs');
    
    //using interal webapp or iron:router
    WebApp.connectHandlers.use('/uploadSomeWhere',function(req,res){
        //var start = Date.now()        
        var file = fs.createWriteStream('/path/to/dir/filename'); 
    
        file.on('error',function(error){...});
        file.on('finish',function(){
            res.writeHead(...) 
            res.end(); //end the respone 
            //console.log('Finish uploading, time taken: ' + Date.now() - start);
        });
    
        req.pipe(file); //pipe the request to the file
    });
    

    설명

    클라이언트의 파일은, 움켜되는 XHR 객체가 생성되고 파일은 서버에 'POST'를 통해 전송됩니다.

    서버에서 데이터는 기본 파일 시스템에 파이프됩니다. 당신은 또한, 파일 이름을 결정 sanitisation을 수행하거나 저장하기 전에 이미 등이있는 경우 확인할 수 있습니다.

    프로

    단점

    /*** client.js ***/
    
    //same as option 2
    
    
    /*** version A: server.js ***/  
    
    var db = MongoInternals.defaultRemoteCollectionDriver().mongo.db;
    var GridStore = MongoInternals.NpmModule.GridStore;
    
    WebApp.connectHandlers.use('/uploadSomeWhere',function(req,res){
        //var start = Date.now()        
        var file = new GridStore(db,'filename','w');
    
        file.open(function(error,gs){
            file.stream(true); //true will close the file automatically once piping finishes
    
            file.on('error',function(e){...});
            file.on('end',function(){
                res.end(); //send end respone
                //console.log('Finish uploading, time taken: ' + Date.now() - start);
            });
    
            req.pipe(file);
        });     
    });
    
    /*** version B: server.js ***/  
    
    var db = MongoInternals.defaultRemoteCollectionDriver().mongo.db;
    var GridStore = Npm.require('mongodb').GridStore; //also need to add Npm.depends({mongodb:'2.0.13'}) in package.js
    
    WebApp.connectHandlers.use('/uploadSomeWhere',function(req,res){
        //var start = Date.now()        
        var file = new GridStore(db,'filename','w').stream(true); //start the stream 
    
        file.on('error',function(e){...});
        file.on('end',function(){
            res.end(); //send end respone
            //console.log('Finish uploading, time taken: ' + Date.now() - start);
        });
        req.pipe(file);
    });     
    

    설명

    클라이언트 스크립트는 옵션 2와 동일하다.

    유성 1.0.x는 mongo_driver.js 마지막 줄에 따르면, MongoInternals라는 전역 객체가 노출되어, 당신은 defaultRemoteCollectionDriver ()가 GridStore에 필요한 현재 데이터베이스 DB 개체를 반환 호출 할 수 있습니다. 버전 A에서 GridStore 또한 MongoInternals에 의해 노출되어있다. 현재 유성 의해 사용 몽고는 v1.4.x이고

    그런 다음 경로 내에서, 당신은 var 파일 = 새로운 GridStore (...) (API)를 호출하여 새 쓰기 개체를 만들 수 있습니다. 그런 다음 파일을 열고 스트림을 생성합니다.

    나는 또한 GridStore가 ( 'MongoDB를') Npm.require를 통해 새로운 MongoDB의 드라이브를 사용하여 호출되는이 버전에서는 버전 B를 포함,이 몽고이 글을 쓰는 시점에서 최신 v2.0.13입니다. 새로운 API는 직접 스트림 (true)를 호출하고 배관을 시작할 수 있습니다, 파일을 열 필요가 없습니다

    프로

    단점

    기준 당신은 옵션 2 옵션 3에서 볼 수있는, 내가 var에 시작 = Date.now ()과 끝을 쓸 때, 나는 MS의 시간을 CONSOLE.LOG을 포함, 아래의 결과이다. 듀얼 코어 4 기가 바이트 RAM, HDD, 우분투 14.04를 기반으로.

    file size   GridFS  FS
    100 KB      50      2
    1 MB        400     30
    10 MB       3500    100
    200 MB      80000   1240
    

    당신은 FS 훨씬 빠르게 GridFS보다 것을 볼 수 있습니다. 2백메가바이트의 파일의 경우, ~ GridFS하지만 FS 만 ~ 1 초를 사용하여 80 초 걸립니다. 내가 SSD를 시도하지 않은, 결과는 다를 수 있습니다. 그러나, 현실에서, 대역폭은 파일 200 MB / 초의 전송 속도를 달성, 클라이언트에서 서버로 스트리밍 일반적이지 않습니다 얼마나 빨리 지시 할 수있다. 다른 한편, 전송 속도 2 ~ MB / 초 (GridFS는) 더 규범이다.

    결론

    더으로이 포괄적 인 의미,하지만 당신은 당신의 필요에 가장 적합한 옵션을 결정할 수 있습니다.

    희망이 곧 유성 DDP 캐싱 등, gzip을 지원하고 GridFS 빠르게 할 수 있습니다 ...

  2. ==============================

    2.안녕 단지 파일의보기에 대한 옵션 1에 추가합니다. 나는 ejson없이했다.

    안녕 단지 파일의보기에 대한 옵션 1에 추가합니다. 나는 ejson없이했다.

    <template name='tryUpload'>
      <p>Choose file to upload</p>
      <input name="upload" class='fileupload' type='file'>
    </template>
    
    Template.tryUpload.events({
    'change .fileupload':function(event,template){
    console.log('change & view');
    var f = event.target.files[0];//assuming upload 1 file only
    if(!f) return;
    var r = new FileReader();
    r.onload=function(event){
      var buffer = new Uint8Array(r.result);//convert to binary
      for (var i = 0, strLen = r.length; i < strLen; i++){
        buffer[i] = r.charCodeAt(i);
      }
      var toString = String.fromCharCode.apply(null, buffer );
      console.log(toString);
      //Meteor.call('saveFiles',buffer);
    }
    r.readAsArrayBuffer(f);};
    
  3. from https://stackoverflow.com/questions/27934141/meteor-uploading-file-from-client-to-mongo-collection-vs-file-system-vs-gridfs by cc-by-sa and MIT license