2017-10-17 16 views
1

J'ai lu plusieurs blogs sur la sauvegarde du fichier en utilisant mgo, mais incapable de trouver une solution pour le besoin spécifique ci-dessous, aider shoutout!Sauvegarde pdf dans MongoDb en utilisant GoLang mgo

Ci-dessous inserts qu'objet dans MongoDB:

var dbSchoolPojo dbSchool 
i := bson.NewObjectId() 
dbSchoolPojo.ID = i 
coll := db.C("school") 
coll.Insert(&dbSchoolPojo) 

Ci-dessous pu se procurer le fichier:

file, handler, err := r.FormFile("pdf") //Able to get file from r *http.Request 

Maintenant, avant d'insérer l'objet, je dois mettre au-dessus fichier comme:

dbSchoolPojo.pdf = file.Bytes(); //Of course Bytes() is invalid method 

Mon objet structs:

type dbSchool struct { 
    ID bson.ObjectId `json:"id" bson:"_id,omitempty"` 
    ... 
    Pdf []byte `json:"pdf" bson:"pdf"` 
    ... 
} 

En profane, la question est: Comment puis-je insérer un fichier (reçu à partir du formulaire HTML) dans mongoDb via GoLang struct en utilisant le pilote mgo?

Merci d'avoir lu! :)


Mise à jour:

PDF est stocké dans MongoDB comme ci-dessous:

Binary('EWHKDSH876KJHlkjdswsddsfsd3232432njnjkn2dljDSFSDFIJSFD333...') 

Ci-dessous le code fonctionne sans erreur, mais ne sert pas le fichier PDF:

func DownloadPdf(w http.ResponseWriter, r *http.Request, db mongoDB) { 
    var school dbSchool 
    coll := db.C("schools") 

    incomingId = "59e6404e2f68182a74610f19"; //This mongo DB _id is received from GET URL request 

    err := coll.Find(bson.M{"_id": bson.ObjectIdHex(incomingId)}). 
     Select(bson.M{"pdf": 1}).One(&school) 
    if err != nil { 
     serve404(w, r, db) 
     return 
    } 

    buffer := school.Pdf 
    w.Header().Set("Content-Disposition", "attachment; filename=abc.pdf") 
    w.Header().Set("Content-Type", "application/pdf") 
    w.Header().Set("Content-Length", strconv.Itoa(len(buffer))) 

    if _, err := w.Write(buffer); err != nil { 
     log.Println("unable to serve image.") //This line is not executed 
    } 
} 

JQuery co de demander le contenu:

 $(".downloadPdfFile").click(function() { 
      var domain = document.location.origin; 
      window.open(domain+'/brochure/59e6404e2f68182a74610f19', '_blank'); 
     }); 

Répondre

2

Le file retourné par Request.FormFile() est de type multipart.File qui est:

type File interface { 
    io.Reader 
    io.ReaderAt 
    io.Seeker 
    io.Closer 
} 

Il implémente io.Reader, vous pouvez tout simplement lire son contenu par exemple avec ioutil.ReadAll():

data, err := io.ReadAll(file) 
// Handle error 

Puis:

dbSchoolPojo.Pdfdata = data 

Mais le stockage de gros fichiers dans le cadre des documents n'est pas optimale/efficace. Au lieu de cela, jetez un oeil à la MongoDB GridFS qui est également pris en charge par mgo: Database.GridFS().

Voilà comment vous pouvez stocker un fichier dans MongoDB GridFS (exemple tiré de GridFS.Create()):

func check(err error) { 
    if err != nil { 
     panic(err.String()) 
    } 
} 
file, err := db.GridFS("fs").Create("myfile.txt") 
check(err) 
n, err := file.Write([]byte("Hello world!")) 
check(err) 
err = file.Close() 
check(err) 
fmt.Printf("%d bytes written\n", n) 

En utilisant GridFS, vous pouvez également enregistrer le fichier sans avoir à lire tout son contenu d'abord en mémoire, si vous "stream" le contenu du fichier dans le mgo.GridFile, car il implémente io.Writer.Appel io.Copy():

// ... 
file, handler, err := r.FormFile("pdfFile") 

// ... 
mongoFile, err := db.GridFS("fs").Create("somepdf.pdf") 
check(err) 

// Now stream from HTTP request into the mongo file: 
written, err := io.Copy(mongoFile, file) 
// Handle err 

err = mongoFile.Close() 
check(err) 

Edit: mise à jour de répondre à votre mise à jour

Lorsque vous servez le PDF, vous interrogez le document dans une mauvaise façon:

err := coll.Find(bson.M{"_id": bson.ObjectIdHex(incomingId)}). 
    Select(bson.M{"pdf": 1}).One(&school) 

Vous sélectionnez le champ pdf à récupérer, mais vos documents dans MongoDB n'ont pas ce champ:

type dbSchool struct { 
    ID bson.ObjectId `json:"id" bson:"_id,omitempty"` 
    ... 
    Pdfdata []byte `json:"pdf"` 
    ... 
} 

Cette définition de type aura pour résultat un champ pdfdata, mais pas pdf. Ajoutez la balise appropriée mgo struct:

type dbSchool struct { 
    ID bson.ObjectId `json:"id" bson:"_id,omitempty"` 
    ... 
    Pdfdata []byte `json:"pdf" bson:"pdf"` 
    ... 
} 

Ou changer le champ sélectionné pdf-pdfdata.

+0

Bonjour @icza, ça a marché! Une autre question: Maintenant, je reçois des données octet dans l'objet struct, l'étape suivante consiste à convertir ces données en fichier pdf et permettre à l'utilisateur de le télécharger via un navigateur Web. Pouvez-vous aider avec ça? –

+0

@NikhilJoshi Pour commencer à vérifier cette question: [le téléchargement de PDF ne fonctionne pas de serverside dans golang] (https://stackoverflow.com/questions/41238407/pdf-download-is-not-working-from-serverside-in- Golang). – icza

+0

Bonjour @icza, j'ai essayé mais ça ne marche pas complètement. S'il vous plaît voir UPDATE dans le message original. –