בקטע הזה מוסבר על הוספה לאינדקס במהדורת Firestore Enterprise. כברירת מחדל, מהדורת Firestore Enterprise לא יוצרת אינדקסים. כדי להפחית את העלויות ולשפר את הביצועים של מסד הנתונים, כדאי ליצור אינדקסים לשאילתות הנפוצות ביותר.
לאינדקסים יש השפעה גדולה על הביצועים של מסד נתונים. אם קיים אינדקס לשאילתה, מסד הנתונים יכול להחזיר תוצאות ביעילות על ידי צמצום כמות הנתונים שצריך לסרוק וצמצום העבודה הדרושה למיון התוצאות. עם זאת, רשומות באינדקס מגדילות את עלויות האחסון ואת כמות העבודה שמתבצעת במהלך פעולת כתיבה בשדות שנוסף להם אינדקס.
הגדרה ומבנה של אינדקס
אינדקס מורכב מהרכיבים הבאים:
- מזהה אוסף
- רשימת שדות באוסף הנתון
- מצב אינדקס לכל שדה: בסדר עולה, בסדר יורד או array-contains
אינדקס יכול גם להפעיל את האפשרויות sparse או unique.
סדר האינדקס
הסדר וכיוון המיון של כל שדה מגדירים את האינדקס באופן ייחודי. לדוגמה, שני האינדקסים הבאים הם אינדקסים נפרדים ואי אפשר להחליף ביניהם:
| איסוף | שדות |
|---|---|
| ערים | מדינה (בסדר עולה), אוכלוסייה (בסדר יורד) |
| ערים | אוכלוסייה (בסדר יורד), מדינה (בסדר עולה), |
כשיוצרים אינדקס כדי לתמוך בשאילתה, צריך לכלול את השדות באותו סדר כמו בשאילתה.
צפיפות האינדקס
כברירת מחדל, רשומות האינדקס מאחסנות נתונים מכל המסמכים באוסף. אינדקס כזה נקרא אינדקס לא דליל. רשומה תתווסף לאינדקס של מסמך, גם אם המסמך לא מכיל אף אחד מהשדות שצוינו באינדקס. שדות שלא קיימים נחשבים כבעלי ערך NULL כשנוצרים רשומות באינדקס. כדי לשנות את ההתנהגות הזו, אפשר להגדיר את האינדקס כאינדקס דליל.
אינדקסים דלילים
אינדקס דליל מוסיף לאינדקס רק את המסמכים באוסף שמכילים ערך (כולל null) בשדה אחד לפחות מהשדות שנוספו לאינדקס. אינדקס דליל מפחית את עלויות האחסון ויכול לשפר את הביצועים.
אינדקסים של Array-contains
כדי לשפר את ביצועי השאילתות כששולחים שאילתה לשדה מערך באמצעות array-contains או array-contains-any, אפשר להוסיף את השדה לאינדקס במצב array-contains. באינדקס יכול להיות שדה אחד לכל היותר במצב array-contains.
כשמוסיפים לאינדקס שדה של מערך במצב array-contains, מנוע השאילתות יכול לאתר במהירות מסמכים שמכילים ערכים ספציפיים של מערכים. בלי אינדקס, השאילתות בודקות את ערכי המערך על ידי סריקה מלאה של האוסף, מה שמאריך את זמן האחזור של השאילתות ומגדיל את עלויות הקריאה ככל שהאוסף גדל.
כדי להוסיף לאינדקס שדה מערך, השדה צריך לעמוד בדרישה הבאה:
- דרישה למערך לא ריק: רשומת אינדקס נוצרת רק אם שדה המערך קיים במסמך והוא מערך לא ריק. מסמכים עם שדות חסרים, שדות שאינם מערכים או שדות של מערכים ריקים לא נוספים לאינדקס.
איך הצפיפות קשורה לאינדקסים של array-contains
באינדקסים שכוללים שדה array-contains, כללי צפיפות האינדקס חלים רק על השדות המסודרים באינדקס. אם מתקיימת הדרישה למערך לא ריק, כללי הצפיפות חלים על שאר השדות הממוינים שנוספו לאינדקס:
- אינדקס לא דליל (
DENSE): נוצרת רשומת אינדקס למסמך. שדות ממוינים לאינדקס שחסרים באינדקס נשמרים כ-nullברשומת האינדקס. - אינדקס חסכוני (
SPARSE): רשומה באינדקס נוצרת רק אם לפחות אחד מהשדות המסודרים שנוספו לאינדקס קיים במסמך.
דוגמה: יצירת ערך באינדקס
לדוגמה, באינדקס users (tags[*], status ASC):
| מסמך | אינדקס NON-SPARSE |
אינדקס SPARSE |
|---|---|---|
{ |
נוסף לאינדקס: • (תגים: "news", סטטוס: "active") |
נוסף לאינדקס: • (תגים: "news", סטטוס: "active") |
{ |
נוספו לאינדקס: • (תגים: "news", סטטוס: "active") • (תגים: "sports", סטטוס: "active") |
נוספו לאינדקס: • (תגים: "news", סטטוס: "active") • (תגים: "sports", סטטוס: "active") |
{ |
נוסף לאינדקס: • (תגים: "news", סטטוס: "active") (הוסרו כפילויות) |
נוסף לאינדקס: • (תגים: "news", סטטוס: "active") (הוסרו כפילויות) |
{ |
נוסף לאינדקס: • (תגים: null, סטטוס: "active") |
נוסף לאינדקס: • (תגים: null, סטטוס: "active") |
{ |
נוסף לאינדקס: • (תגים: "news", סטטוס: null) |
לא נוסף לאינדקס (חסר השדה status) |
{ |
לא נוסף לאינדקס (השדה הוא לא מערך) | לא נוסף לאינדקס (השדה הוא לא מערך) |
{ |
לא נוסף לאינדקס (השדה הוא לא מערך) | לא נוסף לאינדקס (השדה הוא לא מערך) |
{ |
לא נוסף לאינדקס (חסר השדה tags) |
לא נוסף לאינדקס (חסר השדה tags) |
{ |
לא נוסף לאינדקס (מערך ריק) | לא נוסף לאינדקס (מערך ריק) |
שאילתה לדוגמה
אינטרנט
// Query for users where 'tags' contains 'news' and 'status' is 'active' const query = db.collection("users") .where("tags", "array-contains", "news") .where("status", "==", "active"); // Documents returned by the query: // [ // { // "id": "alice", // "tags": ["news", "tech"], // "status": "active" // } // ]
אינדקסים ייחודיים
מגדירים את האפשרות "אינדקס ייחודי" כדי לאכוף ערכים ייחודיים בשדות שנוסף להם אינדקס. באינדקסים של כמה שדות, כל שילוב של ערכים חייב להיות ייחודי באינדקס. מסד הנתונים דוחה כל פעולת עדכון והוספה שמנסה ליצור רשומות אינדקס עם ערכים כפולים. אם הנתונים של השדות שנוסף להם אינדקס מכילים ערכים כפולים, ואתם מנסים ליצור אינדקס ייחודי, בניית האינדקס תיכשל ותופיע הודעת שגיאה בפרטי הפעולה.
שדות חסרים באינדקס ייחודי
אם מוסיפים מסמך שחסרים בו שדות לאינדקס הייחודי, האינדקס מגדיר ערכי null לשדות החסרים. הרשומה שנוצרת באינדקס חייבת להיות ייחודית, אחרת הפעולה תיכשל.
לדוגמה, באינדקס הזה:
| איסוף | שדות שנוספו לאינדקס | היקף השאילתה |
|---|---|---|
| ערים | שם (בסדר עולה) | איסוף |
אם מוסיפים את המסמך {"abbreviation": "LA"} לאוסף, האינדקס הייחודי יוצר רשומה שבה הערך של name מוגדר כ-null. אם תנסו להוסיף את המסמך {"abbreviation": "NYC"}, הפעולה תיכשל כי הרשומה שנוצרת לאינדקס הייחודי זהה.
ההתנהגות הזו רלוונטית גם לאינדקסים ייחודיים עם כמה שדות.
כשיוצרים או מעדכנים מסמך, שדות חסרים שנוספו לאינדקס מוגדרים כ-null, והרשומה שנוצרת באינדקס חייבת להיות ייחודית באינדקס.
אינדקסים ייחודיים בערכי מערך
אינדקס array-contains ייחודי אוסר על מסמכים עם רכיבי מערך חופפים.
סוג האינדקס הזה לא אוכף את הדרישה שלמערך יהיו ערכים ייחודיים במסמך אחד.
לדוגמה, עם אינדקס ייחודי בשדה בשם tags:
אפשר להוסיף את המסמך הבא, doc1:
{
"tags": [ "news", "tech", "news", "music" ]
}
האינדקס מאפשר ערכים כפולים ("news") באותו מערך של מסמך יחיד.
אם תנסו להוסיף מסמך שני, doc2, עם רכיב כפול, הפעולה תיכשל:
{
"tags": [ "sports", "music" ]
}
הפעולה נכשלת כי "music" כבר קיים במערך של doc1 וממופה באינדקס.
אם אתם צריכים לוודא שהרכיבים באותו מערך במסמך אחד הם ייחודיים, טפלו בזה בלוגיקה של האפליקציה.
מערכים ריקים, שדות חסרים וערכי null
בדרך כלל, שדות חסרים באינדקס ייחודי נחשבים כ-null וחייבים להיות ייחודיים בכל המסמכים (ראו שדות חסרים באינדקס ייחודי).
עם זאת, באינדקסים ייחודיים בשדות של מערכים:
- מערכים ריקים, שדות חסרים וערכי null עצמאיים: אם שדה המערך ריק, חסר לגמרי או מכיל ערך
nullעצמאי (לא בתוך מערך), לא נוצרים מפתחות אינדקס למסמך. לכן, למספר מסמכים יכולים להיות שדות ריקים או ערכיnullנפרדים בלי להפעיל שגיאות של מפתחות כפולים. - רכיבי Null בתוך מערך: אם המערך מכיל ערך
nullכרכיב (לדוגמה,["news", null]), הרכיבnullנוסף לאינדקס. כל מסמך נוסף שמכיל רכיבnullבשדה המערך שנוסף לו אינדקס ייכשל עם שגיאת מפתח כפול.
פתרון שגיאות בבניית אינדקסים
יכול להיות שתיתקלו בשגיאות בבניית אינדקסים בזמן ניהול האינדקסים. פעולת הוספה לאינדקס יכולה להיכשל אם יש בעיה בנתונים במסד הנתונים. פעולות הוספה לאינדקס יכולות להיכשל מהסיבות הבאות:
- הגעת למגבלת האינדקס. לדוגמה, יכול להיות שהפעולה הגיעה למספר המקסימלי של רשומות אינדקס לכל מסמך. אם יצירת האינדקס נכשלת, תופיע הודעת שגיאה. אם לא הגעתם למגבלת האינדקס, נסו שוב את פעולת האינדקס.
- הגדרתם את האפשרות של אינדקס ייחודי, והנתונים של השדות שנוסף להם אינדקס ייצרו רשומות אינדקס כפולות. כדי להמשיך, צריך להסיר מהנתונים שילובים כפולים של ערכים.