Όπως σε όλες τις relational databases έτσι και στην Cosmos DB οι indexes έχουν κυρίαρχη θέση καθώς είναι η κηροζίνη των ερωτημάτων και πρέπει να γνωρίζουμε για αυτούς.
Automatic Indexing
Όλα τα documents σε ένα collection στην Cosmos DB αυτόματα γίνονται indexed με βάση το επιλεγμένο partition key και το Id, και αυτό αποτελεί τον primary index.
Εκτός όμως από αυτόν αυτόματα δημιουργούνται και secondary indexes για κάθε property του document και είναι κάτι που δουλεύει αρκετά καλά σε πολλές περιπτώσεις αλλά όπως πάντα υπάρχει και η άλλη πλευρά στο νόμισμα.
Indexing Policy
Στην Cosmos DB υπάρχει αυτό που ονομάζεται indexing policy και μπορείτε να το βρείτε στο azure portal στο Cosmos DB account > Database > Collection > Scale & Settings.
Το indexing policy είναι ένα json document που περιέχει όλα όσα επηρεάζουν την δημιουργία των indexes στην Cosmos DB και είναι το παρακάτω
Για να δούμε κάθε ένα από αυτά τα properties που ορίζουν το indexing policy
Indexing Mode
Με αυτό ορίζεται πότε οι Indexes θα γίνονται update και έχουμε τρεις διαφορετικές επιλογές
- Consistent: Οι indexes γίνονται update σύγχρονα κάθε φορά που έχω ένα write operation (create, replace, delete). Είναι το default και όπως και στις relational databases έχω overhead στα write operations το οποίο εξαρτάται από το μέγεθος των δεδομένων, αλλά είναι και το επιθυμητό από όλους.
- Lazy: οι indexes γίνονται update ασύγχρονα κάθε φορά που έχω write operation και σε στιγμές που το σύστημα έχει διαθέσιμους του κατάλληλους πόρους. Φυσικά με το τρόπο αυτό δεν έχω το όποιο overhead αλλά οι indexes δεν είναι πάντα updated και αυτό σημαίνει ότι στα ερωτήματα μου θα έχω διαφορετικά αποτελέσματα.
- None: δεν έχω indexes και αυτό σημαίνει ότι μπορώ να κάνω αναζητήσεις μόνο με το Id ή το self-URL. Επίσης αν είχα indexes και επιλέξω αυτή την επιλογή διαγράφονται οι υπάρχοντες. Αυτή η επιλογή είναι ουσιαστικά χρήσιμη μόνο όταν έχω key-value storage.
Automatic property
Με αυτό ορίζεται αν θα δημιουργούνται αυτόματα οι indexes και το default είναι true. Αν το κάνουμε false θα πρέπει μόνοι μας να ορίζουμε σε κάθε document την στιγμή που το καταχωρούμε τους index που θέλουμε να έχει.
Included Paths
Tα json documents στην Cosmos DB διαχειρίζονται σαν tree hierarchy και έτσι κάθε property σε αυτά είναι και ένα path στην ιεραρχία.
To path ξεκινάει από το root (“/”) και αυτό ορίζεται στο path property.
Κάθε path τελειώνει με κάποιο από τα παρακάτω patterns:
- * : δηλώνει τα πάντα μετά από το συγκεκριμένο path/property
- ? : δηλώνει ότι υπάρχουν πολλαπλές τιμές για το συγκεκριμένο path/property
- [] : δηλώνει όλα τα elements στο array
Example
{
"firstName": "Kitsos",
"lastName": "Leventis",
"children":[
{
"name": "Pentagiotisa",
"age": "20",
"school":{
"grade": "15",
"classes":[
{
"name": "Argaleios"
},
{
"name": "Pleximo"
},
{
"name": "Mageiriki"
}
]
}
},
{
"name": "Astero",
"age": "20",
"school":{
"grade": "12",
"classes":[
{
"name": "Argaleios"
},
{
"name": "Anagnosi"
},
{
"name": "Pleximo"
}
]
}
}
]
}
Αν θέλω να έχω index για
- lastName το path είναι /lastName
- την ηλικία των παιδιών το path είναι /children/age/?
- τα μαθήματα των παιδιών το path είναι /children/school/*
- το πρώτο μάθημα των παιδιών το path είναι /children/school/classes[0]/name/?
Μπορώ να έχω όσα includedPaths θέλω (σε array) αλλά κάθε ειδικό κάνει overwrite το γενικό δηλαδή το /children/age/? Κάνει overwrite το /*
Other Index Properties
Για κάθε path υπάρχουν και άλλα properties που μπορώ να ορίζω στο indexing policy όπως
- dataType: το data type του index και οι τιμές που μπορώ να βάλω είναι String, Number, Point, Polygon, LineString.
- kind: ο τύπος του index και μπορεί να είναι:
- Hash: το hash της κάθε τιμής μπαίνει στον index και αυτού του τύπου index είναι κατάλληλοι για συγκρίσεις ισότητας και joins
- Range: εύρη των τιμών μπαίνουν σε αυτούς και είναι χρήσιμοι σε ερωτήματα με ισότητες, με από – έως και όταν έχω order by
- Spatial: χρήσιμοι για γεωγραφικά στίγματα και εφαρμόζονται στα point, polygon, linestring data types.
- Precision: ορίζει το μέγεθος που index δηλαδή το πόσα δεδομένα θα έχει. Για τους hash indexes η τιμή είναι 1-8 με default to 3, για τους range indexes το default είναι -1 και σημαίνει high precision αλλά μπορεί να είναι 1-100 με το 100 να είναι το high precision. Για να υποστηριχθεί το order by θέλουμε high precision index.
Excluded Paths
Με αυτό το property ορίζουμε τα path που δεν θέλουμε να γίνουν indexed και είναι και αυτό ένα json array. Tα paths ορίζονται όπως ακριβώς και στα included paths.
Considerations
Υπάρχουν κάποια πράγματα που πρέπει να γνωρίζουμε γύρω από τους indexes στην Cosmos DB όπως:
Παίρνουμε μήνυμα λάθους και δεν γίνεται η εκτέλεση αν έχουμε range query / operation ή query με order by ή spatial data και δεν έχουμε το αντίστοιχο index.
Αν έχουμε order by query και δεν έχουμε τον αντίστοιχο range index ή δεν έχουμε high precision και θέλουμε να εκτελέσουμε αυτό μπορούμε στο REST API header να κάνουμε true to EnableScanInQuery option
FeedOptions options = new FeedOptions();
options.EnableScanInQuery = true;
var query = this.client.CreateDocumentQuery<ThermometerReading>(temperatureCollection, querySpec, options);
//antonch