אינדקסים הם גורם חשוב בביצועים של מסד נתונים. בדומה לאינדקס של ספר שממפה נושאים בספר למספרי דפים, אינדקס של מסד נתונים ממפה את הפריטים במסד הנתונים למיקומים שלהם במסד הנתונים. כששולחים שאילתה למסד נתונים, הוא יכול להשתמש במדד כדי לזהות במהירות את המיקומים של הפריטים שביקשת.
בדף הזה מתוארים שני הסוגים של אינדקסים שבהם Cloud Firestore משתמש: אינדקסים של שדה יחיד ואינדקסים מורכבים.
ההגדרה והמבנה של האינדקס
אינדקס מוגדר על רשימה של שדות במסמך נתון, עם מצב אינדקס תואם לכל שדה.
אינדקס מכיל רשומה לכל שדה שצוין בהגדרת האינדקס. המדד כולל את כל המסמכים שיכולים להיות תוצאות של שאילתות שמבוססות על המדד. מסמך נכלל באינדקס רק אם מוגדר לו ערך שנוסף לאינדקס לכל שדה שנעשה בו שימוש באינדקס. אם הגדרת האינדקס מתייחסת לשדה שלא הוגדר לו ערך במסמך, המסמך לא יופיע באינדקס. במקרה כזה, המסמך אף פעם לא יוחזר כתוצאה של שאילתות שמבוססות על האינדקס.
האינדקס המורכב ממוין לפי ערכי השדות, לפי הסדר שצוין בהגדרת האינדקס.
אינדקס שמאחורי כל שאילתה
אם אין אינדקס לשאילתה, רוב מסדי הנתונים סרקים את התוכן שלהם פריט אחרי פריט. זהו תהליך איטי שמאט עוד יותר ככל שמסד הנתונים גדל. Cloud Firestore מבטיח ביצועים גבוהים של שאילתות באמצעות שימוש במפתחות אינדקס לכל השאילתות. כתוצאה מכך, ביצועי השאילתה תלויים בגודל של קבוצת התוצאות ולא במספר הפריטים במסד הנתונים.
פחות ניהול של אינדקסים, יותר פיתוח אפליקציות
Cloud Firestore כולל תכונות שמקצרות את משך הזמן הנדרש לניהול האינדקס. האינדקסים הנדרשים לשאילתות הבסיסיות ביותר נוצרים באופן אוטומטי. כשאתם משתמשים באפליקציה ובודקים אותה, Cloud Firestore עוזר לכם לזהות וליצור אינדקסים נוספים שנדרשים לאפליקציה.
סוגי מדדים
ב-Cloud Firestore נעשה שימוש בשני סוגי אינדקסים: שדה יחיד ומורכב. בנוסף למספר השדות שנוספו לאינדקס, יש הבדלים בין אינדקסים של שדה יחיד לאינדקסים מורכבים גם באופן הניהול שלהם.
אינדקסים של שדה יחיד
אינדקס של שדה יחיד מאחסן מיפוי ממוין של כל המסמכים באוסף שמכילים שדה ספציפי. כל רשומה באינדקס של שדה יחיד מתעדת את הערך של מסמך בשדה ספציפי ואת המיקום של המסמך במסד הנתונים. Cloud Firestore משתמש באינדקסים האלה כדי לבצע הרבה שאילתות בסיסיות. כדי לנהל אינדקסים של שדה יחיד, צריך להגדיר את ההגדרות של ההוספה האוטומטית לאינדקס ואת ההחרגות מהוספה לאינדקס של מסד הנתונים.
הוספה אוטומטית לאינדקס
כברירת מחדל, Cloud Firestore שומרת באופן אוטומטי אינדקסים של שדה יחיד לכל שדה במסמך וכל שדה משנה במפה. Cloud Firestore משתמש בהגדרות ברירת המחדל הבאות למפתחות של שדה יחיד:
לכל שדה שאינו מערך או מפה, Cloud Firestore מגדיר שני אינדקסים של שדה יחיד ברמת האוסף, אחד במצב עולה ואחד במצב יורד.
לכל שדה מפה, Cloud Firestore יוצר את הפריטים הבאים:
- אינדקס עולה אחד ברמת האוסף לכל שדה משנה שאינו מערך או מפה.
- אינדקס יורד אחד ברמת האוסף לכל שדה משנה שאינו מערך או מפה.
- אינדקס אחד של מערך-מכיל ברמת האוסף לכל שדה משנה של מערך.
- Cloud Firestore יוצר אינדקס באופן רפלקסיבי לכל שדה משנה של המפה.
לכל שדה מערך במסמך, Cloud Firestore יוצר ומנהל אינדקס של מערך שמכיל אוסף.
אינדקסים של שדה יחיד ברמת קבוצת האוספים לא מתוחזקים כברירת מחדל.
החרגות באינדקס של שדה יחיד
כדי לפטור שדה מההגדרות של הוספה אוטומטית לאינדקס, יוצרים החרגה של שדה יחיד מהאינדקס. החרגה מהוספה לאינדקס מבטלת את הגדרות האינדקס האוטומטיות ברמת מסד הנתונים. באמצעות החרגה אפשר להפעיל אינדקס של שדה יחיד שההגדרות של ההוספה האוטומטית לאינדקס היו משביתות אותו, או להשבית אינדקס של שדה יחיד שההוספה האוטומטית לאינדקס הייתה מפעילה אותו. במאמר שיטות מומלצות להוספה לאינדקס מפורטות דוגמאות למקרים שבהם החרגות יכולות להיות שימושיות.
אפשר להשתמש בערך הנתיב של השדה *
כדי להוסיף החרגות מהאינדקס ברמת הקולקציה לכל השדות בקבוצת הקולקציות. לדוגמה, בקבוצת האוספים comments
, מגדירים את נתיב השדה כ-*
כדי להתאים לכל השדות בקבוצת האוספים comments
, ומשביתים את ההוספה לאינדקס של כל השדות בקבוצת האוספים. לאחר מכן תוכלו להוסיף החרגות כדי להוסיף לאינדקס רק את השדות הנדרשים לשאילתות שלכם. הפחתת מספר השדות שנוספו לאינדקס מפחיתה את עלויות האחסון ויכולה לשפר את ביצועי הכתיבה.
אם יוצרים החרגה של שדה יחיד מהאינדקס בשדה מפה, השדות המשניים של המפה יורשים את ההגדרות האלה. עם זאת, אפשר להגדיר החרגות של שדות בודדים לאינדקס בשדות משנה ספציפיים. אם מוחקים פטור בשדה משנה, השדה המשנה יקבל בירושה את הגדרות הפטור של השדה ההורה, אם הן קיימות, או את ההגדרות ברמת מסד הנתונים, אם אין פטורים ברמת ההורה.
במאמר ניהול אינדקסים מוסבר איך יוצרים ומנהלים החרגות של אינדקס עם שדה יחיד.
אינדקסים מורכבים
אינדקס מורכב מאחסן מיפוי ממוין של כל המסמכים באוסף, על סמך רשימה מסודרת של שדות להוספה לאינדקס.
ב-Cloud Firestore נעשה שימוש באינדקסים מורכבים כדי לתמוך בשאילתות שעדיין אין להן תמיכה באינדקסים של שדה יחיד.
Cloud Firestore לא יוצרת באופן אוטומטי אינדקסים מורכבים כמו שהיא עושה באינדקסים של שדה יחיד, בגלל המספר הגדול של שילובי השדות האפשריים. במקום זאת, Cloud Firestore עוזר לכם לזהות וליצור את המדדים המשולבים הנדרשים בזמן פיתוח האפליקציה.
בכל פעם שמנסים להריץ שאילתה שלא נתמכת על ידי אינדקס, הפונקציה Cloud Firestore מחזירה הודעת שגיאה עם קישור ליצירת האינדקס החסר.
אפשר גם להגדיר ולנהל באופן ידני אינדקסים מורכבים באמצעות המסוף או באמצעות CLI של Firebase. מידע נוסף על יצירה וניהול של אינדקסים מורכבים זמין במאמר ניהול אינדקסים.
מצבי הוספה לאינדקס והיקפי שאילתות
ההגדרה של אינדקסים של שדה יחיד ושל אינדקסים מורכבים שונה, אבל בשני המקרים צריך להגדיר את המצבים של האינדקסים ואת היקפי השאילתות שלהם.
מצבי אינדקס
כשמגדירים אינדקס, בוחרים מצב אינדקס לכל שדה שנוסף לאינדקס. כל מצב של אינדקס בשדה תומך בתנאי שאילתות ספציפיים בשדה הזה. אפשר לבחור מבין מצבי האינדקס הבאים:
מצב אינדקס | תיאור |
---|---|
עלייה | השדה תומך בתנאי שאילתות < , <= , == , >= , > , != , in ו-not-in , ותומך במיון התוצאות בסדר עולה על סמך ערך השדה הזה. |
יורד | השדה תומך בתנאי השאילתה < , <= , == , >= , > , != , in ו-not-in , ותומך במיון התוצאות בסדר יורד על סמך ערך השדה הזה. |
Array‑contains | השדה תומך בתנאי שאילתות מסוג array-contains ו-array-contains-any . |
Vector | תמיכה בתנאי שאילתות של FindNearest בשדה. |
היקפי שאילתות
כל אינדקס מוגדר לאוסף או לקבוצת אוספים. זה נקרא היקף השאילתה של האינדקס:
- היקף האוסף כברירת מחדל,
- Cloud Firestore יוצרת אינדקסים ברמת האוסף. המדדים האלה תומכים בשאילתות שמחזירות תוצאות מתוך אוסף יחיד.
- היקף קבוצת האוספים
- קבוצת קולקציות כוללת את כל הקולקציות עם אותו מזהה קולקציה. כדי להריץ שאילתת קבוצת אוספים שמציגה תוצאות מסוננות או ממוינות מקבוצת אוספים, צריך ליצור אינדקס תואם ברמת קבוצת האוספים.
סדר ברירת המחדל והשדה __name__
בנוסף למיון המסמכים לפי מצבי האינדקס שצוינו לכל שדה (עולה או יורד) , האינדקסים מחילים מיון סופי לפי השדה __name__
של כל מסמך. הערך של השדה __name__
מוגדר לנתיב המלא של המסמך. כלומר, מסמכים בקבוצת התוצאות עם אותם ערכי שדות ממוינים לפי נתיב המסמך.
כברירת מחדל, השדה __name__
ממוין באותו כיוון של השדה הממוין האחרון בהגדרת האינדקס. לדוגמה:
איסוף | שדות שנוספו לאינדקס | היקף השאילתה |
---|---|---|
ערים | __name__ |
name, איסוף |
ערים | המצב __name__ |
, איסוף |
ערים | __name__ |
country, population, איסוף |
כדי למיין את התוצאות לפי כיוון __name__
שאינו ברירת המחדל, צריך ליצור את האינדקס הזה.
מאפייני אינדקס
אינדקס שמאפשר לבצע את השאילתה בצורה היעילה ביותר מוגדר לפי המאפיינים הבאים:
- שדות שמשמשים במסנני שוויון
- שדות שמשמשים בסדרי מיון
- שדות שמשמשים במסנני טווחים ובמסנני אי-שוויון (שעדיין לא נכללים בסדרי המיון)
- שדות שמשמשים בצבירה (שעדיין לא נכללים בסדרי מיון ובמסנני טווחים וחוסר שוויון)
Cloud Firestore מחשב את התוצאות של השאילתות באופן הבא:
- מזהה את האינדקס התואם לאוסף, למאפייני המסנן, למפעילי המסנן ולסדרי המיון של השאילתה.
- מזהה את מיקום האינדקס שממנו מתחילה הסריקה. תחילת המיקום מתחילה במסנני השוויון של השאילתה ומסתיימת במסנני הטווח והאי-שוויון בשדה
orderBy
הראשון. - התהליך מתחיל לסרוק את האינדקס, ומחזיר כל מסמך שעונה על כל המסננים, עד שתהליך הסריקה יבצע אחת מהפעולות הבאות:
- נתקל במסמך שלא עומד בתנאי הסינון ומאשר שמסמך עתידי לא יעמוד לעולם בתנאי הסינון במלואם.
- מגיעים לסוף האינדקס.
- איסוף של מספר התוצאות המקסימלי המבוקש בשאילתה.
דוגמה להוספה לאינדקס
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")
איסוף | שדות שנוספו לאינדקס | היקף השאילתה |
---|---|---|
ערים | country, population | איסוף |
cities | 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()
רשומות אינדקס
מספר הרשומות של מסמך מסוים באינדקס נקבע לפי המבנה של המסמך והאינדקסים שהוגדרו בפרויקט. רשומות אינדקס נספרות כחלק מהמגבלה על מספר הרשומות באינדקס.
הדוגמה הבאה ממחישה את הרשומות של המסמך ב-Index.
מסמך
/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
- מערך השכונות מכיל (ASC ו-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 |
מערך השכונות מכיל ASC | שכונות: "Mission" |
מערך השכונות מכיל DESC | שכונות: "Mission" |
מערך השכונות מכיל ASC | שכונות: 'מרכז העיר' |
מערך השכונות מכיל DESC | שכונות: 'מרכז העיר' |
מערך השכונות מכיל ASC | שכונות: "Marina" |
מערך השכונות מכיל DESC | שכונות: "Marina" |
רשומות של אינדקס מורכב | |
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 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")
אפשר ליצור אינדקס לכל שאילתה:
איסוף | שדות שנוספו לאינדקס | היקף השאילתה |
---|---|---|
מסעדות | 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
) זמין בדף פתרון הבעיות.