מדריך MongoDB: שימוש ב-GridFS

במאמר הקודם למדנו על אינדקסים ב-MongoDB. במאמר הזה אנו נלמד על אחד מהפיצ'רים היותר מגניבים של MongoDB: אחסון קבצים מכל סוג שהוא! כן! נכון שאפשר לעשות את זה גם ב-MySQL, אבל ב-MongoDB יש לאחסון הקבצים כמה יתרונות חשובים והחשוב שבהם הוא ש-MongoDB בנוי יותר מ-MySQL להרחבה במקרה וצריך ליצור כמה מכונות שונות שיתמכו באפליקציה. במקרה הזה לא תצטרכו לשבור את הראש יותר מדי על חלוקת הקבצים למכונות השונות - MongoDB יעשה את זה עבורכם.

סביר מאוד להניח שבניגוד למדריכים אחרים, לא תצטרכו את תוכן המדריך הזה. כולנו עובדים עם MongoDB באמצעות אבסטרקציות ששפת התכנות מספקת לנו – וזה לא משנה אם אנו עובדים באמצעות node.js, PHP, Java או net. – בסופו של דבר כל נושא העלאת הקבצים והטיפול בהם באמצעות האבסטרקציה הוא שקוף. אבל שווה מאוד ללמוד איך GridFS עובד במקרה ומשהו משתבש.

הטיפול בקבצים (וב-documents מעל 16MB) נעשה באמצעות GridFS שזו תוספת ל-MongoDB שמגיעה יחד איתו – בין אם אתם עובדים על לינוקס או חלונות. אם תכנסו לקונסולה של לינוקס ותכתבו:


mongofiles --version
 version 2.6.4

תוכלו לראות את הגרסה של mongofiles. אם יש לכם חלונות, תכנסו ל-cmd לתיקיה שבה הצבתם את קבצי ה-mongo ותכתבו mongofiles.exe –version – זה אמור לעבוד היטב. בכל הדוגמאות כאן, שבהן אני מתיחס ללינוקס, פשוט תקחו את השורה של הלינוקס ותוסיפי exe. ל-mongofiles – זה יעבוד – באחריות (ותעברו כבר ללינוקס! זה באמת קל!).

על מנת להעלות קובץ ל-MongoDB, אנחנו צריכים קובץ – אם אין לכם אחד כזה אפשר לייצר אותו באמצעות השורה:


dd if=/dev/zero of=demo.test bs=524288 count=1

זה יצור לי demo.test במשקל חצי מגהבייט. אבל כל קובץ כלשהו יהיה מספיק טוב – אפילו תמונה של בר רפאלי (כי אין כמו SEO על הבוקר 🙂 ).

אחרי שהתפקסתי על קובץ, אני צריך להעלות אותו ל-GridFS – את זה אני עושה באמצעות


mongofiles -d test put demo.test 

כאשר demo.test זה שם הקובץ שלנו. רגע, מה הולך פה? קודם כל אני משתמש ב-mongofiles אחרי כן באופרטור -d test- האופרטור הזה חשוב – כי כאן אני מציין לאיזה מסד נתונים אני הולך להכניס את הקובץ – במקרה הזה אני הולך להכניס את הקובץ למסד נתונים test. אחרי זה אני משתמש במילה put ואז את שם הקובץ.

התוצאה צריכה להיות משהו כזה:


connected to: 127.0.0.1
added file: { _id: ObjectId('541fd00c54af6edf6f9cb818'), filename: "demo.test", chunkSize: 261120, uploadDate: new Date(1411371020875), md5: "59071590099d21dd439896592338bf95", length: 524288 }
done!

אם נכנס ל-mongo ונציץ ב-collections שיש לנו ב-db שאליו הכנסנו את הקובץ, נגלה שיש לנו שני collections חדשים!


fs.chunks
fs.files

ב-chunks יש את המידע עצמו של הקובץ, כאשר כשמו כן הוא – הקובץ מחולק למספר חלקים כשכל חלק מקושר למטא מידע שנמצא ב-files. אם נסתכל על ה-files נראה שם את הקבצים, או במקרה הזה את הקובץ היחידי שהכנסנו.


db.fs.files.find({})
{ "_id" : ObjectId("541fd00c54af6edf6f9cb818"), "filename" : "demo.test", "chunkSize" : 261120, "uploadDate" : ISODate("2014-09-22T07:30:20.875Z"), "md5" : "59071590099d21dd439896592338bf95", "length" : 524288 }

אפשר לראות גם את החלקים שהקובץ חולק אליהם, את גודלם ואת הגודל הכללי של הקובץ. מה שחשוב הוא ה-ObjectId.

את הקבצים אנו יכולים לחפש, יש להם ObjectId אז אנחנו יכולים לעשות להם reference בקלות רבה ל-collections אחרים. אנחנו גם יכולים לשלוף את ה-chunks עם ה-ObjectId – שימושי במקרים של קבצי טקסט, קצת פחות במקרים של קבצים בינאריים.

ואיך אנו קוראים לקובץ? גם באמצעות mongofiles:


mongofiles get demo.test 

כדי לראות את כל הקבצים, אנו יכולים להשתמש ב:


mongofiles list

יש עוד כמה דברים שאפשר לעשות עם mongofiles (שווה להשקיע כמה דקות ולראות את ה help– שלו), אבל בעקרון רובנו לא נעשה אותם כי כאמור סביר מאוד להניח שאם תשתמשו ב-GridFS תעשו את זה באמצעות class שינהל את זה עבורכם. מה שחשוב הוא להבין שבסופו של יום, הקבצים נכנסים לשני collections – האחד ששמו הוא chunks שמכיל את חלקי הקובץ והשני הוא files שמכיל את המידע על הקובץ עצמו – כולל ה-ObjectId שלו. ב-files יש כבר אינדוקס אוטומטי של ה-filename, מה שהופך את כל נושא חיפוש הקבצים ליותר מהיר.

במאמר הבא אנו נדבר על איך מייבאים ומייצאים קובץ של MongoDB.

פוסטים נוספים שכדאי לקרוא

גלילה לראש העמוד