מדריך 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.

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

פתרונות ומאמרים על פיתוח אינטרנט

יישום של nonce על מנת להגן מפני התקפות injection

בפוסט הקודם הסברתי על hash עם CSP על משאבי inline – שזה נחמד ומעולה אבל פחות ישים בעולם האמיתי שבו בדרך כלל התוכן ה-inline (בין

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