מדדים הם גורם חשוב בביצועים של מסד נתונים. בדומה לאינדקס של ספר שממפה נושאים בספר למספרי דפים, אינדקס של מסד נתונים ממפה את הפריטים במסד הנתונים למיקומים שלהם במסד הנתונים. כששולחים שאילתה למסד נתונים, הוא יכול להשתמש במדד כדי לזהות במהירות את המיקומים של הפריטים שביקשת.
בדף הזה מתוארים שני סוגי האינדקסים שבהם 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-any . |
Vector | תומכת בתנאי שאילתה של FindNearest בשדה. |
היקפי שאילתות
כל אינדקס מתייחס לאוספים או לקבוצת אוספים. זה נקרא היקף השאילתה של האינדקס:
- היקף האוסף כברירת מחדל,
- Cloud Firestore יוצרת אינדקסים ברמת האוסף. האינדקסים האלה תומכים בשאילתות שמחזירות תוצאות מאוסף יחיד.
- היקף קבוצת האוספים
- קבוצת קולקציות כוללת את כל הקולקציות עם אותו מזהה קולקציה. כדי להריץ שאילתת קבוצת אוספים שמציגה תוצאות מסוננות או ממוינות מקבוצת אוספים, צריך ליצור אינדקס תואם ברמת קבוצת האוספים.
סדר ברירת המחדל והשדה __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"]
אינדקסים של שדה יחיד
- שם_עיר ASC
- city_name DESC
- temperatures.summer ASC
- temperatures.summer DESC
- טמפרטורות.winter ASC
- טמפרטורות.winter – תיאור
- מערך השכונות מכיל (ASC ו-DESC)
אינדקסים מורכבים
- City_name ASC, שכונות ARRAY
- city_name DESC, neighborhoods ARRAY
רשומות באינדקס
הגדרת ההוספה לאינדקס הזו מובילה לרשומות האינדקס הבאות של המסמך:
אינדקס | נתונים שנוספו לאינדקס |
---|---|
רשומות באינדקס של שדה יחיד | |
שם_עיר 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" |
עיר_name DESC, שכונות ARRAY | city_name: "San Francisco", neighborhoods: "Mission" |
city_name DESC, neighborhoods ARRAY | city_name: "San Francisco", neighborhoods: "Downtown" |
עיר_name DESC, שכונות 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 | איסוף |
מסעדות | עיר אחת ( | ), דירוג_כוכבים אחד ( )איסוף |
מסעדות | category, city, star_rating | איסוף |
מסעדות | category, city, editors_pick, star_rating | איסוף |
כפתרון טוב יותר, אתם יכולים לצמצם את מספר האינדקסים על ידי ניצול היכולת של Cloud Firestore למזג מדדים עבור תנאי שוויון:
איסוף | שדות שנוספו לאינדקס | היקף השאילתה |
---|---|---|
מסעדות | category, 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
) זמין בדף לפתרון בעיות.