Catch up on everthing we announced at this year's Firebase Summit. Learn more

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

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

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

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

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

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

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

סוגי אינדקס

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

אינדקסים של שדה בודד

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

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

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

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

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

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

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

פטורים ממדדים בשדה יחיד

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

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

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

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

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

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

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

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

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

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

מצבי אינדקס

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

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

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

כל אינדקס הוא בהיקף של אוסף או קבוצת אוסף. זה ידוע בתור היקף השאילתה של האינדקס:

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

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

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

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

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

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

אינטרנט
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")
אוסף שדות הוספו לאינדקס היקף שאילתה
ערים הארץ, האוכלוסייה אוסף
ערים הארץ, האוכלוסייה אוסף

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

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

כדי להדגים אינדקס עם היקף של קבוצת אוסף, לדמיין תוסיף 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()

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

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

הנה דוגמה להמחשה.

מסמך

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

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

  • שם (אוטומטי) ASC & DESC
  • (אוטומטי) טמפרטורות ASC & DESC
  • (אוטומטי) שכונות מערך מכיל

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

  • שם ASC, שכונות ASC
  • שם DESC, שכונות ASC

ערכי אינדקס כתוצאה מכך

תצורת הוספה לאינדקס מביאה ל-12 ערכי האינדקס הבאים עבור המסמך:

אינדקס כְּנִיסָה
שם ASC & DESC שם: "סן פרנסיסקו"
טמפרטורות ASC & DESC טמפרטורות.קיץ: 67
טמפרטורות ASC & DESC טמפרטורות.חורף: 55
מערך שכונות מכיל שכונות: "משימה"
מערך שכונות מכיל שכונות: "מרכז העיר"
מערך שכונות מכיל שכונות: "מרינה"
שם ASC, שכונות ASC שם: "סן פרנסיסקו", שכונות: "משימה"
שם ASC, שכונות ASC שם: "סן פרנסיסקו", שכונות: "מרכז העיר"
שם ASC, שכונות ASC שם: "סן פרנסיסקו", שכונות: "מרינה"
שם DESC, שכונות ASC שם: "סן פרנסיסקו", שכונות: "משימה"
שם DESC, שכונות ASC שם: "סן פרנסיסקו", שכונות: "מרכז העיר"
שם DESC, שכונות ASC שם: "סן פרנסיסקו", שכונות: "מרינה"

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

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

ניצול מיזוג אינדקס

למרות ש-Cloud Firestore משתמשת באינדקס עבור כל שאילתה, היא לא בהכרח דורשת אינדקס אחד לכל שאילתה. לבירורים עם שוויון מרובה ( == ) סעיפים, ואם נרצה בכך, גידול orderBy סעיף, ענן Firestore יכול לעשות שימוש חוזר אינדקסים קיימים. Cloud 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")

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

אוסף שדות הוספו לאינדקס היקף שאילתה
מסעדות הקטגוריה, STAR_RATING אוסף
מסעדות העיר, STAR_RATING אוסף
מסעדות הקטגוריה, העיר, STAR_RATING אוסף
מסעדות הקטגוריה, העיר, Editors_Pick, STAR_RATING אוסף

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

אוסף שדות הוספו לאינדקס היקף שאילתה
מסעדות הקטגוריה, STAR_RATING אוסף
מסעדות העיר, STAR_RATING אוסף
מסעדות Editors_Pick, STAR_RATING אוסף

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

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

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

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

לְהַגבִּיל פרטים
מספר מקסימלי של אינדקסים מורכבים עבור מסד נתונים 200
מספר מקסימלי של פטורים על אינדקס של שדה בודד עבור מסד נתונים 200

מספר מרבי של ערכי אינדקס עבור כל מסמך

40,000

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

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

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

גודל מקסימלי של ערך אינדקס

7.5 KiB

כדי לראות כיצד Google Cloud Firestore מחשבת גודל הכניסה למדד, לראות בגודל כניסה למדד .

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

8 MiB

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

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

    1500 בתים

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

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

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

    מקרה תיאור
    שדות מיתר גדולים

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

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

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

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

    מערך גדול או שדות מפה

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