מדריך MongoDB: מודלים של מידע: Embedded Documents

הסבר על embedded document ב-MongoDB. אחד מהפיצ'רים היותר חשובים במסד הנתונים הזה.

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

עד כה, ה-documents שלנו נראו די מעפנים, משהו בסגנון:


{ "_id" : ObjectId("541e99d7f5e52579d9d7b625"), "title" : "number 14", "body" : "Page Body Number 14" }

אבל אפשר לעשות documents יותר רציניים מזה, יש הרבה מאוד סוגי נתונים ש-MongoDB תומך בהם. אם נתיחס לדוגמה שהשתמשנו בה במאמר הקודם למשל, עמודים שלכל אחד מהם תגובות. אני יכול – לצורך העניין – ליצור את ה-documents של התגובות בתוך ה-document של הדף! כלומר סוג של sub documents!

נשמע מבלבל? בכלל לא! בואו ותראו את הדוגמה הבאה:


db.pages.insert({
    "title": "Page Title",
    "body": "Page Body",
    "comments": [
        {
            "comment_title": "Comment Number 1",
            "comment_body": "Comment Number 1"
        }, {
            "comment_title": "Comment Number 2",
            "comment_body": "Comment Number 2"
        }
    ]
})

כאן אני יוצר עמוד שיש לו שתי תגובות. איך זה נראה?


> db.pages.find({
    "_id": ObjectId("541ead1ef5e52579d9d7b681")
}) 


{
    "_id": ObjectId("541ead1ef5e52579d9d7b681"),
    "title": "Page Title",
    "body": "Page Body",
    "comments": [{
        "comment_title": "Comment Number 1",
        "comment_body": "Comment Number 1"
    }, {
        "comment_title": "Comment Number 2",
        "comment_body": "Comment Number 2"
    }]
}

אם אני רוצה לעדכן את ה-comments (להוסיף או למחוק) אני יכול לעשות את זה במגוון דרכים – בדיוק כמו כל ערך רגיל. רק שה-update יהיה מעט יותר מורכב. והשליפה? בדיוק כמו שליפה רגילה – מקבלים את כל האובייקט. זה הכוח העיקרי מאחורי MongoDB – הסכימה היא גמישה לחלוטין ואנחנו יכולים ליצור document מורכב ולא מנורמל כרצוננו.

אם אני רוצה לבצע שאילתה באמצעות שימוש בתכונה שקיימת ב-sub document, אין יותר קל מזה. למשל – שאילתת חיפוש שמחפש אחרי Comment Number 1 תראה כך:


db.pages.find({"comments.comment_title":"Comment Number 1"})

שימו לב שהסינטקס של JavaScript משחק פה תפקיד – קודם כל התכונה הראשית – comments ואז התכונה המשנית שהיא comment_title. מה מפריד ביניהן? נקודה – בדיוק כמו ב-JavaScript.

התוצאה, אגב – היא האובייקט כולו כמובן.

מתי להשתמש במודל הזה? המודל הזה עובד מעולה כאשר אנו מבצעים קריאות. הקריאה תתבצע במהירות ותחזיר את כל המידע שאנחנו צריכים. אם אנחנו יכולים להסיק בודאות שאנו תמיד נרצה את התגובות עם העמוד, ולתגובות אין זכות קיום ללא העמוד – Embedded Documents זה רעיון טוב. אבל – כאשר אנו משתמשים ב-Embedded document, אנו מפסידים זמן יקר בכתיבה. כלומר כל כתיבה 'נועלת' את ה-document ואם יש לנו מספר כתיבות – זה אומר שיש לנו בעית ביצועים. אז האם יש תשובה מוחלטת? לא. זה בהתאם לצרכי האפליקציה שלכם. לפעמים שימוש ב-reference יהיה יותר נבון ולפעמים שימוש ב-Embedded documents. בדוקומנטציה הרשמית יש כמה design patterns שכדאי להציץ בהן במקרה שאתם מתלבטים.

במאמר הבא נדבר על אינדקסים ב-MongoDB.

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

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

המנעו מהעלאת source control לשרת פומבי

לא תאמינו כמה אתרים מעלים את ה-source control שלהם לשרת. ככה תמצאו אותם וגם הסבר למה זה רעיון רע.

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