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

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

ממנטו עם גמל אין לי מושג למה אני עושה דברים
יסודות בתכנות

מה זה stateful ו-stateless

מה זה סטייט? למה אנחנו צריכים לדעת מה זה ואיך רואים את זה ממש בעיניים.

בינה מלאכותית

התקנה של Openclaw על רספברי פיי

איך מתקינים את הלהיט החדש בתחום על רספברי פיי? קל ופשוט ללא חומרה מיוחדת ועם הסבר מפורט.

בינה מלאכותית

בעיות אמיתיות של אבטחה באייג׳נטים

אייג׳נטים יכולים להיות תמימים להחריד, בפוסט הזה שמלווה פרק מיוחד בפודקאסט עמוק ב-Bots, אנחנו נראה הגנות והתקפות על אייג׳נטים.

בינה מלאכותית

איך אייג׳נט מבוסס LLM עובד?

הסבר בסיסי על איך אייג׳נט עם כלים עובד ואפילו איך בונים אחד מאפס עם פייתון בלבד.

יסודות בתכנות

פוסט אקראי במיוחד על רנדומליות

איך רנדומליות מחושבת באמת במחשב? האם באמת המספרים שאנחנו מקבלים מפונקציות קריפטוגרפיות הן באמת רנדומליות? ולמה זה חשוב?

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