האינדקסים הם גורם חשוב בביצועים של מסד נתונים. בדומה לאינדקס של ספר שממפה נושאים בספר למספרי עמודים, אינדקס של מסד נתונים ממפה את הפריטים במסד הנתונים למיקומים שלהם במסד הנתונים. כשמריצים שאילתה במסד נתונים, מסד הנתונים יכול להשתמש באינדקס כדי לזהות במהירות את המיקומים של הפריטים שביקשתם.
בדף הזה מתוארים שני סוגי האינדקסים שבהם נעשה שימוש ב-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 עוזר לכם לזהות וליצור את האינדקסים הנדרשים כשאתם מפתחים את האפליקציה.
בכל פעם שתנסו להריץ שאילתה שלא נתמכת על ידי אינדקס קיים, 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, __name__ |
איסוף |
| ערים | state, __name__ |
איסוף |
| ערים | מדינה, אוכלוסייה, __name__ |
איסוף |
כדי למיין את התוצאות לפי __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 לשדה המערך. כל שורה בטבלה הבאה מייצגת רשומה באינדקס של שדה יחיד:
| איסוף | השדה נוסף לאינדקס | היקף השאילתה |
|---|---|---|
| ערים | שם | איסוף |
| ערים | מדינה | איסוף |
| ערים | מדינה אחת () | איסוף |
| ערים | 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"])לדוגמה, אם רוצים לשלוח שאילתה לגבי ציוני דרך בכל הערים, מריצים את השאילתה הזו בקבוצת האוספים שמורכבת מכל האוספים. צריך גם להפעיל אינדקס של שדה יחיד עם היקף של קבוצת אוספים:landmarkslandmarks
| איסוף | שדות באינדקס | היקף השאילתה |
|---|---|---|
| ציוני דרך | קטגוריה אחת ( או ) | קבוצת אוספים |
אחרי שמפעילים את האינדקס הזה, אפשר לשלוח שאילתה לקבוצת האוספים 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
- שכונות DESC
- temperatures ASC
- temperatures DESC
- temperatures.summer ASC
- temperatures.summer DESC
- temperatures.winter ASC
- temperatures.winter DESC
- neighborhoods Array Contains
מדדים ידניים
- 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"] |
| שכונות DESC | neighborhoods: ["Mission", "Downtown", "Marina"] |
| temperatures ASC | temperatures: {summer: 67, winter: 55} |
| temperatures DESC | temperatures: {summer: 67, winter: 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 |
| neighborhoods Array Contains | שכונות: Mission |
| neighborhoods Array Contains | שכונות: "Downtown" |
| neighborhoods Array Contains | שכונות: "מרינה" |
| ערכים ידניים לאינדקס | |
| 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) זמין בדף לפתרון בעיות.