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

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

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

בדף הזה מתוארים שני סוגי האינדקסים שבהם נעשה שימוש ב-Firestore Standard edition: אינדקסים אוטומטיים ואינדקסים ידניים.

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

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

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

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

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

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

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

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

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

במהדורת Standard של Firestore יש שני סוגים של אינדקסים: אוטומטיים וידניים. ההבדל בין אינדקסים ידניים לאינדקסים אוטומטיים הוא באופן הניהול שלהם.

אינדקסים אוטומטיים

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

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

מהדורת Firestore Standard משתמשת בהגדרות ברירת המחדל הבאות לאינדקסים אוטומטיים:

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

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

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

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

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

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

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

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

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

מדדים ידניים

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

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

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

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

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

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

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

מצבי אינדקס

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

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

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

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

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

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

סידור אוטומטי והשדה __name__

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

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

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

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

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

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

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

ב-Firestore Standard edition, התוצאות של שאילתות מחושבות באופן הבא:

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

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

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

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

אינטרנט
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"] });

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

אוסף השדה נוסף לאינדקס היקף השאילתה
ערים שם אוסף
ערים מדינה אוסף
ערים מדינה אחת () אוסף
ערים 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"])

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

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

אינטרנט
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
  • שכונות ASC
  • neighborhoods DESC
  • ‫temperatures ASC
  • temperatures DESC
  • temperatures.summer ASC
  • temperatures.summer DESC
  • temperatures.winter ASC
  • temperatures.winter 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"
שכונות ASC neighborhoods: ["Mission", "Downtown", "Marina"]
neighborhoods DESC neighborhoods: ["Mission", "Downtown", "Marina"]
‫temperatures ASC טמפרטורות: {קיץ: 67, חורף: 55}
temperatures DESC טמפרטורות: {קיץ: 67, חורף: 55}
temperatures.summer ASC temperatures.summer: 67
temperatures.summer DESC temperatures.summer: 67
temperatures.winter ASC temperatures.winter: 55
temperatures.winter DESC temperatures.winter: 55
מערך של שכונות מכיל שכונות: Mission
מערך של שכונות מכיל שכונות: Downtown
מערך של שכונות מכיל שכונות: "מרינה"
ערכים ידניים לאינדקס
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"

אינדקסים ותמחור

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

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

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

כדי להפחית את עלויות ההוספה לאינדקס, כדאי לזהות מצבים שבהם אפשר להשתמש במיזוג אינדקסים. לדוגמה, ב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 אוסף

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

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

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

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

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

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

בדף הזה מפורטות המכסות והמגבלות על הבקשות במהדורת Standard של Firestore.

הגבלה פרטים
המספר המקסימלי של אינדקסים מורכבים למסד נתונים
  • ‫200 אם לא הפעלתם חיוב בפרויקט Google Cloud .

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

  • ‫1,000 כשמפעילים את החיוב בפרויקט Google Cloud .

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

מספר מקסימלי של הגדרות של שדה יחיד למסד נתונים
  • ‫200 אם לא הפעלתם חיוב בפרויקט Google Cloud .

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

  • ‫1,000 כשמפעילים את החיוב בפרויקט Google Cloud .

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

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

40,000

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

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

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

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

7.5 KiB

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

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

‎8 MiB

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

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

    ‫1,500 בייטים

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

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

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

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

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

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

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

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

    שדות TTL

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

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

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

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

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