סוגי אינדקסים ב-Cloud Firestore

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

בדף הזה מתוארים שני סוגי האינדקסים שבהם נעשה שימוש ב-Cloud Firestore: אינדקסים של שדה יחיד ואינדקסים מורכבים.

הגדרה ומבנה של אינדקס

אינדקס מוגדר ברשימה של שדות במסמך נתון, עם מצב אינדקס תואם לכל שדה.

אינדקס מכיל רשומה לכל שדה שמופיע בהגדרת האינדקס. האינדקס כולל את כל המסמכים שיכולים להיות תוצאות של שאילתות שמבוססות על האינדקס. מסמך נכלל באינדקס רק אם מוגדר לו ערך באינדקס לכל שדה שמשמש באינדקס. אם הגדרת האינדקס מתייחסת לשדה שלא הוגדר לו ערך במסמך, המסמך לא יופיע באינדקס. במקרה כזה, המסמך לא יוחזר אף פעם כתוצאה של שאילתה שמבוססת על האינדקס.

האינדקס המורכב ממוין לפי ערכי השדות, בסדר שצוין בהגדרת האינדקס.

אינדקס מאחורי כל שאילתה

אם לא קיים אינדקס לשאילתה, רוב מסדי הנתונים סורקים את התוכן שלהם פריט אחר פריט. זהו תהליך איטי שמתארך ככל שמסד הנתונים גדל. ‫Cloud Firestore מבטיח ביצועים גבוהים של שאילתות באמצעות שימוש באינדקסים עבור כל השאילתות. כתוצאה מכך, ביצועי השאילתה תלויים בגודל של קבוצת התוצאות ולא במספר הפריטים במסד הנתונים.

פחות ניהול של אינדקסים, יותר פיתוח אפליקציות

Cloud Firestore כולל תכונות שמקטינות את כמות הזמן שצריך להשקיע בניהול האינדקסים. האינדקסים שנדרשים לשאילתות הבסיסיות ביותר נוצרים בשבילכם באופן אוטומטי. במהלך השימוש באפליקציה ובדיקתה, Cloud Firestore עוזר לכם לזהות את המדדים הנוספים שהאפליקציה צריכה וליצור אותם.

סוגי אינדקסים

ב-Cloud Firestore יש שני סוגים של אינדקסים: אינדקס של שדה יחיד ואינדקס מורכב. בנוסף למספר השדות שנוספו לאינדקס, יש הבדל בין אינדקסים של שדה יחיד לבין אינדקסים מורכבים באופן שבו מנהלים אותם.

אינדקסים של שדה יחיד

אינדקס של שדה יחיד מאחסן מיפוי ממוין של כל המסמכים באוסף שמכילים שדה ספציפי. כל רשומה באינדקס של שדה יחיד מתעדת את הערך של מסמך בשדה ספציפי ואת המיקום של המסמך במסד הנתונים. ‫Cloud Firestore משתמש באינדקסים האלה כדי לבצע הרבה שאילתות בסיסיות. אתם יכולים לנהל אינדקסים של שדה יחיד על ידי הגדרת ההגדרות של האינדקס האוטומטי של מסד הנתונים והחרגות של אינדקסים.

הוספה אוטומטית לאינדקס

כברירת מחדל, Cloud Firestore מתחזק באופן אוטומטי אינדקסים של שדה יחיד לכל שדה במסמך ולכל שדה משנה במפה. ‫Cloud Firestore משתמש בהגדרות ברירת המחדל הבאות לאינדקסים של שדה יחיד:

  • לכל שדה שאינו מערך ושאינו מיפוי, Cloud Firestore מגדיר שני אינדקסים של שדה יחיד בהיקף אוסף, אחד במצב עולה ואחד במצב יורד.

  • לכל שדה של מפה, Cloud Firestore יוצר את הפריטים הבאים:

    • אינדקס אחד בסדר עולה ברמת האוסף לכל שדה משנה שאינו מערך או מפה.
    • אינדקס יורד אחד בהיקף אוסף לכל שדה משנה שאינו מערך או מפה.
    • אינדקס אחד של array-contains ברמת האוסף לכל שדה משנה של מערך.
    • Cloud Firestore מבצע אינדוקס לכל שדה משנה של המפה באופן רקורסיבי.
  • לכל שדה מערך במסמך, Cloud Firestore יוצר ומנהל אינדקס מסוג array-contains בהיקף האוסף.

  • אינדקסים של שדה יחיד עם היקף של קבוצת אוספים לא מתוחזקים כברירת מחדל.

פטורים מאינדקס של שדה יחיד

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

אפשר להשתמש בערך של נתיב השדה * כדי להוסיף חריגים לאינדקס ברמת הקולקציה לכל השדות בקבוצת קולקציות. לדוגמה, כדי להתאים את כל השדות בקבוצת האוסף comments ולהשבית את יצירת האינדקס של כל השדות בקבוצת האוסף, מגדירים את נתיב השדה ל-*.comments לאחר מכן אפשר להוסיף פטורים כדי ליצור אינדקס רק לשדות שנדרשים לשאילתות. צמצום מספר השדות באינדקס מפחית את עלויות האחסון ויכול לשפר את ביצועי הכתיבה.

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

במאמר ניהול אינדקסים מוסבר איך ליצור ולנהל חריגות באינדקסים של שדה יחיד.

אינדקסים מורכבים

אינדקס מורכב מאחסן מיפוי ממוין של כל המסמכים באוסף, על סמך רשימה מסודרת של שדות לאינדקס.

Cloud Firestore משתמש באינדקסים מורכבים כדי לתמוך בשאילתות שלא נתמכות כבר על ידי אינדקסים של שדה יחיד.

Cloud Firestore לא יוצר באופן אוטומטי אינדקסים מורכבים כמו שהוא עושה לאינדקסים של שדה יחיד, בגלל המספר הגדול של שילובי שדות אפשריים. במקום זאת, Cloud Firestore עוזר לכם לזהות וליצור אינדקסים מורכבים נדרשים בזמן שאתם מפתחים את האפליקציה.

בכל פעם שתנסו להריץ שאילתה שלא נתמכת על ידי אינדקס, Cloud Firestore תחזיר הודעת שגיאה עם קישור שאפשר ללחוץ עליו כדי ליצור את האינדקס החסר.

אפשר גם להגדיר ולנהל אינדקסים מורכבים באופן ידני באמצעות המסוף או באמצעות Firebase CLI. מידע נוסף על יצירה וניהול של אינדקסים מורכבים זמין במאמר ניהול אינדקסים.

מצבי אינדקס והיקפי שאילתות

ההגדרה של אינדקסים של שדה יחיד ושל אינדקסים מורכבים שונה, אבל בשני המקרים צריך להגדיר את מצבי האינדקס ואת היקפי השאילתות של האינדקסים.

מצבי אינדקס

כשמגדירים אינדקס, בוחרים מצב אינדקס לכל שדה באינדקס. כל שדה תומך בסעיפי שאילתה ספציפיים בשדה הזה, בהתאם למצב האינדקס שלו. אפשר לבחור מבין מצבי האינדקס הבאים:

מצב אינדקס תיאור
עולה השדה תומך בסעיפי שאילתה <,‏ <=,‏ ==,‏ >=,‏ >,‏ !=,‏ in ו-not-in, ותומך במיון התוצאות בסדר עולה על סמך הערך של השדה הזה.
סדר יורד תומך בסעיפי שאילתה <, ‏ <=, ‏ ==, ‏ >=, ‏ >, ‏ !=, ‏ in ו-not-in בשדה, ותומך במיון תוצאות בסדר יורד על סמך ערך השדה הזה.
Array‑contains תומך בסעיפי שאילתה array-contains ו-array-contains-any בשדה.
Vector תומך בסעיפי שאילתה FindNearest בשדה.

היקפי שאילתות

כל אינדקס מוגבל לאוסף או לקבוצת אוספים. האזור הזה נקרא היקף השאילתה של האינדקס:

היקף האיסוף
Cloud Firestore יוצרת אינדקסים עם היקף אוסף כברירת מחדל. האינדקסים האלה תומכים בשאילתות שמחזירות תוצאות מאוסף יחיד.

היקף קבוצת האוספים
קבוצת קולקציות כוללת את כל הקולקציות עם אותו מזהה קולקציה. כדי להריץ שאילתה של קבוצת אוספים שמחזירה תוצאות מסוננות או מסודרות מקבוצת אוספים, צריך ליצור אינדקס תואם עם היקף של קבוצת אוספים.

סדר ברירת המחדל והשדה __name__

בנוסף למיון המסמכים לפי מצבי האינדקס שצוינו לכל שדה (סדר עולה או יורד) , האינדקסים מבצעים מיון סופי לפי השדה __name__ של כל מסמך. הערך של השדה __name__ הוא הנתיב המלא של המסמך. המשמעות היא שמסמכים בערכת התוצאות עם אותם ערכי שדות ממוינים לפי נתיב המסמך.

כברירת מחדל, השדה __name__ ממוין באותו כיוון של השדה האחרון שמוין בהגדרת האינדקס. לדוגמה:

איסוף שדות באינדקס היקף השאילתה
ערים שם, __name__ איסוף
ערים state, __name__ איסוף
ערים מדינה, אוכלוסייה, __name__ איסוף

כדי למיין את התוצאות לפי __name__ הכיוון שאינו ברירת המחדל, צריך ליצור את האינדקס הזה.

מאפייני האינדקס

אינדקס שמאפשר להריץ את השאילתה בצורה הכי יעילה מוגדר על ידי המאפיינים הבאים:

  • שדות שמשמשים במסנני שוויון
  • שדות שמשמשים למיון הזמנות
  • שדות שמשמשים במסננים של טווחים ואי-שוויון (שלא נכללים כבר בסדר המיון)
  • שדות שמשמשים לצבירה (שלא נכללים כבר בסדר מיון ובמסננים של טווח ואי-שוויון)

Cloud Firestore מחשב את התוצאות של השאילתות באופן הבא:

  1. מזהה את האינדקס שמתאים לאוסף, למאפייני המסנן, לאופרטורים של המסנן ולסדר המיון של השאילתה.
  2. מזהה את מיקום האינדקס שממנו מתחילה הסריקה. נקודת ההתחלה מופיעה אחרי מסנני השוויון של השאילתה ומסתיימת במסנני הטווח והאי-שוויון בשדה הראשון orderBy.
  3. מתחיל לסרוק את האינדקס, ומחזיר כל מסמך שעומד בכל המסננים, עד שתהליך הסריקה מבצע אחת מהפעולות הבאות:
    • הכלי נתקל במסמך שלא עומד בתנאי הסינון, ומוודא שאף מסמך בהמשך לא יעמוד בתנאי הסינון באופן מלא.
    • ההגעה לסוף האינדקס.
    • מערכת Search Ads 360 אוספת את המספר המקסימלי של תוצאות שצוין בשאילתה.

דוגמה להוספה לאינדקס

Cloud Firestore יוצרת בשבילכם באופן אוטומטי אינדקסים של שדה יחיד, וכך האפליקציה שלכם יכולה לתמוך במהירות בשאילתות בסיסיות ביותר במסד הנתונים. אינדקסים של שדה יחיד מאפשרים לבצע שאילתות פשוטות על סמך ערכי שדות והאופרטורים להשוואה <,‏ <=,‏ ==,‏ >=,‏ > ו-in. בשדות של מערכים, אפשר לבצע שאילתות array-contains ו-array-contains-any.

כדי להמחיש זאת, נבחן את הדוגמאות הבאות מנקודת המבט של יצירת אינדקס. קטע הקוד הבא יוצר כמה מסמכי city באוסף cities ומגדיר את השדות name,‏ state,‏ country,‏ capital,‏ population ו-tags לכל מסמך:

אינטרנט
var citiesRef = db.collection("cities");

citiesRef.doc("SF").set({
    name: "San Francisco", state: "CA", country: "USA",
    capital: false, population: 860000,
    regions: ["west_coast", "norcal"] });
citiesRef.doc("LA").set({
    name: "Los Angeles", state: "CA", country: "USA",
    capital: false, population: 3900000,
    regions: ["west_coast", "socal"] });
citiesRef.doc("DC").set({
    name: "Washington, D.C.", state: null, country: "USA",
    capital: true, population: 680000,
    regions: ["east_coast"] });
citiesRef.doc("TOK").set({
    name: "Tokyo", state: null, country: "Japan",
    capital: true, population: 9000000,
    regions: ["kanto", "honshu"] });
citiesRef.doc("BJ").set({
    name: "Beijing", state: null, country: "China",
    capital: true, population: 21500000,
    regions: ["jingjinji", "hebei"] });

בהנחה שהגדרות ברירת המחדל של יצירת האינדקס האוטומטית מופעלות, Cloud Firestore מעדכן אינדקס אחד של שדה יחיד בסדר עולה לכל שדה שאינו מערך, אינדקס אחד של שדה יחיד בסדר יורד לכל שדה שאינו מערך ואינדקס אחד של שדה יחיד מסוג array-contains לשדה המערך. כל שורה בטבלה הבאה מייצגת רשומה באינדקס של שדה יחיד:

איסוף השדה נוסף לאינדקס היקף השאילתה
ערים שם איסוף
ערים מדינה איסוף
ערים מדינה אחת () איסוף
ערים capital איסוף
ערים אוכלוסייה איסוף
ערים שם איסוף
ערים מדינה איסוף
ערים מדינה אחת () איסוף
ערים capital איסוף
ערים אוכלוסייה איסוף
ערים array-contains אזורים איסוף

שאילתות שנתמכות על ידי אינדקסים של שדה יחיד

בעזרת האינדקסים האלה של שדה יחיד שנוצרים באופן אוטומטי, אפשר להריץ שאילתות פשוטות כמו:

אינטרנט
const stateQuery = citiesRef.where("state", "==", "CA");
const populationQuery = citiesRef.where("population", "<", 100000);
const nameQuery = citiesRef.where("name", ">=", "San Francisco");

אפשר גם ליצור שאילתות של in ושל שוויון מורכב (==):

אינטרנט
citiesRef.where('country', 'in', ["USA", "Japan", "China"])

// Compound equality queries
citiesRef.where("state", "==", "CO").where("name", "==", "Denver")
citiesRef.where("country", "==", "USA")
         .where("capital", "==", false)
         .where("state", "==", "CA")
         .where("population", "==", 860000)

אם אתם צריכים להריץ שאילתה מורכבת שמשתמשת בהשוואה של טווח (<, <=,‏ > או >=) או אם אתם צריכים למיין לפי שדה אחר, אתם צריכים ליצור אינדקס מורכב עבור השאילתה הזו.

האינדקס array-contains מאפשר לשלוח שאילתות לשדה המערך regions:

אינטרנט
citiesRef.where("regions", "array-contains", "west_coast")
// array-contains-any and array-contains use the same indexes
citiesRef.where("regions", "array-contains-any", ["west_coast", "east_coast"])

שאילתות שנתמכות על ידי אינדקסים מורכבים

Cloud Firestore משתמש באינדקסים מורכבים כדי לתמוך בשאילתות מורכבות שלא נתמכות כבר על ידי אינדקסים של שדה יחיד. לדוגמה, תצטרכו אינדקס מורכב לשאילתות הבאות:

אינטרנט
citiesRef.where("country", "==", "USA").orderBy("population", "asc")
citiesRef.where("country", "==", "USA").where("population", "<", 3800000)
citiesRef.where("country", "==", "USA").where("population", ">", 690000)
// in and == clauses use the same index
citiesRef.where("country", "in", ["USA", "Japan", "China"])
         .where("population", ">", 690000)

השאילתות האלה דורשות את האינדקס המורכב שמופיע בהמשך. מכיוון שהשאילתה משתמשת בשוויון (== או in) בשדה country, אפשר להשתמש במצב אינדקס עולה או יורד בשדה הזה. כברירת מחדל, סעיפי אי-שוויון מוחלים בסדר מיון עולה על סמך השדה בסעיף אי-השוויון.

איסוף שדות באינדקס היקף השאילתה
ערים (או ) מדינה, אוכלוסייה איסוף

כדי להריץ את אותן שאילתות אבל עם סדר מיון יורד, צריך אינדקס מורכב נוסף בכיוון יורד עבור population:

אינטרנט
citiesRef.where("country", "==", "USA").orderBy("population", "desc")

citiesRef.where("country", "==", "USA")
         .where("population", "<", 3800000)
         .orderBy("population", "desc")

citiesRef.where("country", "==", "USA")
         .where("population", ">", 690000)
         .orderBy("population", "desc")

citiesRef.where("country", "in", ["USA", "Japan", "China"])
         .where("population", ">", 690000)
         .orderBy("population", "desc")
איסוף שדות באינדקס היקף השאילתה
ערים מדינה, אוכלוסייה איסוף
ערים country, ‏ population איסוף

כדי למנוע ירידה בביצועים שנגרמת כתוצאה ממיזוג אינדקסים, מומלץ ליצור אינדקס מורכב כדי לשלב שאילתת array-contains או array-contains-any עם סעיפים נוספים:

אינטרנט
citiesRef.where("regions", "array-contains", "east_coast")
         .where("capital", "==", true)

// array-contains-any and array-contains use the same index
citiesRef.where("regions", "array-contains-any", ["west_coast", "east_coast"])
         .where("capital", "==", true)
איסוף שדות באינדקס היקף השאילתה
ערים תגי array-contains, ‏ (או ) באותיות רישיות איסוף

שאילתות שנתמכות על ידי אינדקסים של קבוצות אוספים

כדי להדגים אינדקס עם היקף של קבוצת אוספים, מוסיפים landmarks אוסף משנה לחלק ממסמכי city:

אינטרנט
var citiesRef = db.collection("cities");

citiesRef.doc("SF").collection("landmarks").doc().set({
    name: "Golden Gate Bridge",
    category : "bridge" });
citiesRef.doc("SF").collection("landmarks").doc().set({
    name: "Golden Gate Park",
    category : "park" });

citiesRef.doc("DC").collection("landmarks").doc().set({
    name: "National Gallery of Art",
    category : "museum" });
citiesRef.doc("DC").collection("landmarks").doc().set({
    name: "National Mall",
    category : "park" });

באמצעות אינדקס של שדה יחיד עם היקף של קולקציה, אפשר לשלוח שאילתה לקולקציית landmarks של עיר מסוימת על סמך השדה category:

איסוף שדות באינדקס היקף השאילתה
ציוני דרך קטגוריה (או ) איסוף
אינטרנט
citiesRef.doc("SF").collection("landmarks").where("category", "==", "park")
citiesRef.doc("SF").collection("landmarks").where("category", "in", ["park", "museum"])

לדוגמה, אם אתם רוצים להריץ שאילתה על ציוני הדרך בכל הערים, אתם מריצים את השאילתה הזו על קבוצת האוספים שמורכבת מכל האוספים.landmarks צריך גם להפעיל landmarks אינדקס של שדה יחיד עם היקף של קבוצת אוספים:

איסוף שדות באינדקס היקף השאילתה
ציוני דרך קטגוריה (או ) קבוצת אוספים

אחרי שמפעילים את האינדקס הזה, אפשר לשלוח שאילתות לקבוצת האוספים landmarks:

אינטרנט
var landmarksGroupRef = db.collectionGroup("landmarks");

landmarksGroupRef.where("category", "==", "park")
landmarksGroupRef.where("category", "in", ["park", "museum"])

כדי להריץ שאילתה של קבוצת אוספים שמחזירה תוצאות מסוננות או מסודרות, צריך להפעיל אינדקס מתאים של שדה יחיד או אינדקס מורכב עם היקף של קבוצת אוספים. עם זאת, בשאילתות של קבוצות אוספים שלא מסננות או מסדרות את התוצאות, לא נדרשות הגדרות אינדקס נוספות.

לדוגמה, אפשר להריץ את השאילתה הבאה של קבוצת אוספים בלי להפעיל אינדקס נוסף:

אינטרנט
db.collectionGroup("landmarks").get()

ערכים באינדקס

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

בדוגמה הבאה מוצגות רשומות האינדקס של מסמך.

מסמך

/cities/SF

city_name : "San Francisco"
temperatures : {summer: 67, winter: 55}
neighborhoods : ["Mission", "Downtown", "Marina"]

אינדקסים של שדה יחיד

  • city_name ASC
  • city_name DESC
  • temperatures.summer ASC
  • temperatures.summer DESC
  • temperatures.winter ASC
  • temperatures.winter DESC
  • ‫neighborhoods Array Contains (ASC and DESC)

אינדקסים מורכבים

  • city_name ASC, neighborhoods ARRAY
  • city_name DESC, neighborhoods ARRAY

ערכים באינדקס

הגדרת ההוספה לאינדקס הזו יוצרת את רשומות האינדקס הבאות עבור המסמך:

אינדקס נתונים שנוספו לאינדקס
רשומות אינדקס של שדה יחיד
city_name ASC city_name: "San Francisco"
city_name DESC city_name: "San Francisco"
temperatures.summer ASC temperatures.summer: 67
temperatures.summer DESC temperatures.summer: 67
temperatures.winter ASC temperatures.winter: 55
temperatures.winter DESC temperatures.winter: 55
neighborhoods Array Contains ASC שכונות: Mission
‫neighborhoods Array Contains DESC שכונות: Mission
neighborhoods Array Contains ASC שכונות: "מרכז העיר"
‫neighborhoods Array Contains DESC שכונות: "מרכז העיר"
neighborhoods Array Contains ASC שכונות: 'מרינה'
‫neighborhoods Array Contains DESC שכונות: 'מרינה'
רשומות של אינדקסים מורכבים
city_name ASC, neighborhoods ARRAY city_name: "San Francisco", neighborhoods: "Mission"
city_name ASC, neighborhoods ARRAY city_name: "San Francisco", neighborhoods: "Downtown"
city_name ASC, neighborhoods ARRAY city_name: "San Francisco", neighborhoods: "Marina"
city_name DESC, neighborhoods ARRAY city_name: "San Francisco", neighborhoods: "Mission"
city_name DESC, neighborhoods ARRAY city_name: "San Francisco", neighborhoods: "Downtown"
city_name DESC, neighborhoods ARRAY city_name: "San Francisco", neighborhoods: "Marina"

מדדים ותמחור

אינדקסים תורמים לעלויות האחסון של האפליקציה. מידע נוסף על חישוב גודל האחסון של אינדקסים זמין במאמר גודל רשומה באינדקס.

שימוש במיזוג אינדקסים

למרות ש-Cloud Firestore משתמש באינדקס לכל שאילתה, הוא לא בהכרח דורש אינדקס אחד לכל שאילתה. בשביל שאילתות עם כמה סעיפים של שוויון (==) ואופציונלית סעיף orderBy, אפשר לעשות שימוש חוזר באינדקסים קיימים.Cloud FirestoreCloud Firestore יכול למזג את האינדקסים של מסנני שוויון פשוטים כדי לבנות את האינדקסים המורכבים שנדרשים לשאילתות שוויון גדולות יותר.

כדי להפחית את עלויות ההוספה לאינדקס, כדאי לזהות מצבים שבהם אפשר להשתמש במיזוג אינדקסים. לדוגמה, בrestaurantsאוסף של אפליקציה לדירוג מסעדות:

  • מסעדות

    • burgerthyme

      name : "Burger Thyme"
      category : "burgers"
      city : "San Francisco"
      editors_pick : true
      star_rating : 4

האפליקציה הזו משתמשת בשאילתות כמו אלה שבהמשך. האפליקציה משתמשת בשילובים של פסוקיות שוויון עבור category, city ו-editors_pick, ותמיד ממיינת לפי סדר עולה של star_rating:

אינטרנט
db.collection("restaurants").where("category", "==", "burgers")
                            .orderBy("star_rating")

db.collection("restaurants").where("city", "==", "San Francisco")
                            .orderBy("star_rating")

db.collection("restaurants").where("category", "==", "burgers")
                            .where("city", "==", "San Francisco")
                            .orderBy("star_rating")

db.collection("restaurants").where("category", "==", "burgers")
                            .where("city", "==" "San Francisco")
                            .where("editors_pick", "==", true )
                            .orderBy("star_rating")

אפשר ליצור אינדקס לכל שאילתה:

איסוף שדות באינדקס היקף השאילתה
מסעדות category, star_rating איסוף
מסעדות city, star_rating איסוף
מסעדות category, city, star_rating איסוף
מסעדות category, city, editors_pick, star_rating איסוף

פתרון טוב יותר הוא לצמצם את מספר האינדקסים באמצעות היכולת של Cloud Firestore למזג אינדקסים עבור פסוקיות שוויון:

איסוף שדות באינדקס היקף השאילתה
מסעדות category, star_rating איסוף
מסעדות city, star_rating איסוף
מסעדות editors_pick, star_rating איסוף

קבוצת האינדקסים הזו לא רק קטנה יותר, אלא היא גם תומכת בשאילתה נוספת:

אינטרנט
db.collection("restaurants").where("editors_pick", "==", true)
                            .orderBy("star_rating")

מגבלות על הוספה לאינדקס

המגבלות הבאות חלות על אינדקסים. מידע נוסף על מכסות ומגבלות זמין במאמר מכסות ומגבלות.

מגבלה פרטים
המספר המקסימלי של אינדקסים מורכבים למסד נתונים
מספר מקסימלי של הגדרות של שדה יחיד למסד נתונים

הגדרה אחת ברמת השדה יכולה להכיל כמה הגדרות לאותו שדה. לדוגמה, אם יש לכם חריגה מאינדוקס של שדה יחיד ומדיניות TTL באותו שדה, זה נחשב כהגדרה אחת של שדה לצורך המגבלה.

מספר הערכים המקסימלי באינדקס לכל מסמך

40,000

מספר הערכים באינדקס הוא סכום הערכים הבאים במסמך:

  • מספר הרשומות באינדקס של שדה יחיד
  • מספר הרשומות באינדקס המורכב

כדי לראות איך Cloud Firestore הופך מסמך וקבוצה של אינדקסים לרשומות באינדקס, אפשר לעיין בדוגמה הזו של ספירת רשומות באינדקס.

המספר המקסימלי של שדות באינדקס מורכב 100
הגודל המקסימלי של רשומה באינדקס

7.5 KiB

כדי לראות איך Cloud Firestore מחשב את הגודל של רשומה באינדקס, אפשר לעיין במאמר בנושא גודל של רשומה באינדקס.

הסכום המקסימלי של גדלי הערכים באינדקס של מסמך

‎8 MiB

הגודל הכולל הוא סכום הערכים הבאים במסמך:

  • סכום הגודל של רשומות האינדקס של שדה יחיד במסמך
  • סכום הגודל של רשומות האינדקס המורכב של מסמך
  • הגודל המקסימלי של ערך שדה שנוסף לאינדקס

    ‫1,500 בייטים

    ערכי שדות מעל 1,500 בייט נחתכים. שאילתות שכוללות ערכים קטומים של שדות עשויות להחזיר תוצאות לא עקביות.

    שיטות מומלצות ליצירת אינדקס

    ברוב האפליקציות, אפשר להסתמך על יצירת אינדקס אוטומטית ועל הקישורים בהודעת השגיאה כדי לנהל את האינדקסים. עם זאת, יכול להיות שתרצו להוסיף פטורים לשדה יחיד במקרים הבאים:

    נרתיק תיאור
    שדות מחרוזת גדולים

    אם יש לכם שדה מחרוזת שמכיל לעיתים קרובות ערכי מחרוזת ארוכים שאתם לא משתמשים בהם לשאילתות, אתם יכולים להחריג את השדה מהוספה לאינדקס כדי לצמצם את עלויות האחסון.

    שיעורי כתיבה גבוהים לאוסף שמכיל מסמכים עם ערכים עוקבים

    אם יוצרים אינדקס לשדה שערכו גדל או קטן באופן עקבי בין מסמכים באוסף, כמו חותמת זמן, קצב הכתיבה המקסימלי לאוסף הוא 500 כתיבות לשנייה. אם לא מבצעים שאילתה על סמך השדה עם הערכים העוקבים, אפשר להחריג את השדה מהוספה לאינדקס כדי לעקוף את המגבלה הזו.

    בתרחיש שימוש ב-IoT עם קצב כתיבה גבוה, לדוגמה, אוסף שמכיל מסמכים עם שדה של חותמת זמן עשוי להתקרב למגבלה של 500 פעולות כתיבה בשנייה.

    שדות TTL

    אם אתם משתמשים במדיניות TTL (אורך חיים), שימו לב שהשדה TTL חייב להיות חותמת זמן. האינדוקס בשדות TTL מופעל כברירת מחדל ויכול להשפיע על הביצועים בשיעורי תנועה גבוהים יותר. השיטה המומלצת היא להוסיף פטורים של שדה יחיד לשדות ה-TTL.

    שדות של מערכים או מפות גדולים

    שדות גדולים של מערכים או מיפויים יכולים להתקרב למגבלה של 40,000 רשומות אינדקס לכל מסמך. אם אתם לא מבצעים שאילתות על סמך מערך גדול או שדה מיפוי, כדאי להחריג אותו מהוספה לאינדקס.

    אם אתם משתמשים בשאילתות עם אופרטורים של טווח ואי-שוויון בכמה שדות, כדאי לעיין בשיקולים בנושא יצירת אינדקסים כדי לשפר את הביצועים והעלות של שאילתות Cloud Firestore.

    מידע נוסף על פתרון בעיות בהוספה לאינדקס (התרחבות האינדקס, שגיאות INVALID_ARGUMENT) זמין בדף פתרון הבעיות.