במאמר הקודם למדנו על אינדקסים ב-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.
תגובה אחת
רן תודה רבה על המדריך.
אני משתמש ב mongo DB .מנסה לשלוח תמונה מה user ל server ואח"כ להציג באתר, ולא מצליח שלחו אותי לפיתרון של mongofilse, הקובץ נשמר אוטומטי או פקודות מיוחדות לא ממש הבנתי אותך?
והאם הנושא הזה מכוסה בספר שלך על node.js?