MongoDB
Indeksy
Szukaj…
Składnia
db.collection.createIndex({ <string field> : <1|-1 order> [, <string field> : <1|-1 order>] });
Uwagi
Wpływ na wydajność : Należy pamiętać, że indeksy poprawiają wydajność odczytu, ale mogą mieć zły wpływ na wydajność zapisu, ponieważ wstawianie dokumentu wymaga aktualizacji wszystkich indeksów.
Jedno pole
db.people.createIndex({name: 1})
Spowoduje to utworzenie rosnącego indeksu pojedynczego pola na nazwie pola.
W tego typu indeksach kolejność sortowania jest nieistotna, ponieważ mongo może przechodzić przez indeks w obu kierunkach.
Złożony
db.people.createIndex({name: 1, age: -1})
Tworzy to indeks dla wielu pól, w tym przypadku dla pól name
i age
. Będzie rosło z name
i zstępowało z age
.
W tym typie indeksu kolejność sortowania jest istotna, ponieważ określa, czy indeks może obsługiwać operację sortowania, czy nie. Odwrotne sortowanie jest obsługiwane na dowolnym prefiksie indeksu złożonego, o ile sortowanie odbywa się w odwrotnym kierunku sortowania dla wszystkich kluczy w sortowaniu. W przeciwnym razie sortowanie indeksów złożonych musi być zgodne z kolejnością indeksu.
Ważna jest również kolejność pól, w tym przypadku indeks zostanie posortowany najpierw według name
, a w obrębie każdej wartości imienia - według wartości pola age
. Dzięki temu indeks może być używany przez zapytania dotyczące pola name
lub name
i age
, ale nie tylko age
.
Usunąć
Aby upuścić indeks, możesz użyć nazwy indeksu
db.people.dropIndex("nameIndex")
Lub dokument specyfikacji indeksu
db.people.dropIndex({name: 1})
Lista
db.people.getIndexes()
Zwróci to tablicę dokumentów, z których każdy opisuje indeks w kolekcji osób
Podstawy tworzenia indeksu
Zobacz poniższą kolekcję transakcji.
> db.transactions.insert({ cr_dr : "D", amount : 100, fee : 2});
> db.transactions.insert({ cr_dr : "C", amount : 100, fee : 2});
> db.transactions.insert({ cr_dr : "C", amount : 10, fee : 2});
> db.transactions.insert({ cr_dr : "D", amount : 100, fee : 4});
> db.transactions.insert({ cr_dr : "D", amount : 10, fee : 2});
> db.transactions.insert({ cr_dr : "C", amount : 10, fee : 4});
> db.transactions.insert({ cr_dr : "D", amount : 100, fee : 2});
getIndexes()
pokażą wszystkie indeksy dostępne dla kolekcji.
db.transactions.getIndexes();
Zobaczmy wynik powyższej instrukcji.
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "documentation_db.transactions"
}
]
Istnieje już jeden indeks do zbierania transakcji. Wynika to z faktu, że MongoDB tworzy unikalny indeks w polu _id
podczas tworzenia kolekcji. Indeks _id
uniemożliwia klientom wstawianie dwóch dokumentów o tej samej wartości w polu _id
. Nie można upuścić tego indeksu w polu _id
.
Dodajmy teraz indeks dla pola cr_dr;
db.transactions.createIndex({ cr_dr : 1 });
Wynik wykonania indeksu jest następujący.
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
CreatedCollectionAutomatycznie wskazuje, czy operacja utworzyła kolekcję. Jeśli kolekcja nie istnieje, MongoDB tworzy kolekcję w ramach operacji indeksowania.
Pozwól uruchomić db.transactions.getIndexes();
jeszcze raz.
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "documentation_db.transactions"
},
{
"v" : 1,
"key" : {
"cr_dr" : 1
},
"name" : "cr_dr_1",
"ns" : "documentation_db.transactions"
}
]
Teraz widzisz, że kolekcja transakcji ma dwa indeksy. Domyślny indeks _id
i cr_dr_1
które stworzyliśmy. Nazwę przypisuje MongoDB. Możesz ustawić własne imię jak poniżej.
db.transactions.createIndex({ cr_dr : -1 },{name : "index on cr_dr desc"})
Teraz db.transactions.getIndexes();
da ci trzy wskaźniki.
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "documentation_db.transactions"
},
{
"v" : 1,
"key" : {
"cr_dr" : 1
},
"name" : "cr_dr_1",
"ns" : "documentation_db.transactions"
},
{
"v" : 1,
"key" : {
"cr_dr" : -1
},
"name" : "index on cr_dr desc",
"ns" : "documentation_db.transactions"
}
]
Podczas tworzenia indeksu { cr_dr : -1 }
1 oznacza, że indeks będzie w porządku ascending
, a -1 w porządku descending
.
Indeksy zaszyfrowane
Indeksy można również zdefiniować jako mieszane . Jest to bardziej wydajne w przypadku zapytań o równość , ale nie jest skuteczne w przypadku zapytań o zakres ; można jednak zdefiniować zarówno indeksy mieszające, jak i rosnąco / malejąco w tym samym polu.
> db.transactions.createIndex({ cr_dr : "hashed" });
> db.transactions.getIndexes(
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "documentation_db.transactions"
},
{
"v" : 1,
"key" : {
"cr_dr" : "hashed"
},
"name" : "cr_dr_hashed",
"ns" : "documentation_db.transactions"
}
]
Upuszczanie / usuwanie indeksu
Jeśli nazwa indeksu jest znana,
db.collection.dropIndex('name_of_index');
Jeśli nazwa indeksu nie jest znana,
db.collection.dropIndex( { 'name_of_field' : -1 } );
Uzyskaj indeksy kolekcji
db.collection.getIndexes();
Wynik
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "documentation_db.transactions"
},
{
"v" : 1,
"key" : {
"cr_dr" : 1
},
"name" : "cr_dr_1",
"ns" : "documentation_db.transactions"
},
{
"v" : 1,
"key" : {
"cr_dr" : -1
},
"name" : "index on cr_dr desc",
"ns" : "documentation_db.transactions"
}
]
Unikalny indeks
db.collection.createIndex( { "user_id": 1 }, { unique: true } )
wymusza unikalność na zdefiniowanym indeksie (pojedynczym lub złożonym). Budowanie indeksu zakończy się niepowodzeniem, jeśli kolekcja zawiera już zduplikowane wartości; indeksowanie zakończy się niepowodzeniem również z brakiem wielu wpisów (ponieważ wszystkie będą indeksowane z wartością null
), chyba że określono sparse: true
.
Indeksy rzadkie i indeksy częściowe
Rzadkie indeksy:
Mogą być one szczególnie przydatne w przypadku pól, które są opcjonalne, ale które również powinny być unikalne.
{ "_id" : "[email protected]", "nickname" : "Johnnie" }
{ "_id" : "[email protected]" }
{ "_id" : "[email protected]", "nickname" : "Jules"}
{ "_id" : "[email protected]" }
Ponieważ dwa wpisy nie mają określonego „pseudonimu”, a indeksowanie potraktuje nieokreślone pola jako null, utworzenie indeksu zakończy się niepowodzeniem, a 2 dokumenty będą miały „null”, więc:
db.scores.createIndex( { nickname: 1 } , { unique: true, sparse: true } )
pozwoli ci nadal mieć pseudonimy „zerowe”.
Rzadkie indeksy są bardziej kompaktowe, ponieważ pomijają / ignorują dokumenty, które nie określają tego pola. Jeśli więc masz kolekcję, w której tylko mniej niż 10% dokumentów określa to pole, możesz utworzyć znacznie mniejsze indeksy - lepiej wykorzystując ograniczoną pamięć, jeśli chcesz wykonywać zapytania takie jak:
db.scores.find({'nickname': 'Johnnie'})
Indeksy częściowe:
Indeksy częściowe stanowią nadzbiór funkcjonalności oferowanej przez indeksy rzadkie i powinny być preferowane w stosunku do indeksów rzadkich. ( Nowości w wersji 3.2 )
Indeksy częściowe określają wpisy indeksu na podstawie określonego filtru.
db.restaurants.createIndex(
{ cuisine: 1 },
{ partialFilterExpression: { rating: { $gt: 5 } } }
)
Jeśli rating
jest większa niż 5, wówczas cuisine
zostanie zindeksowana. Tak, możemy również określić właściwość do indeksowania na podstawie wartości innych właściwości.
Różnica między indeksami rzadkimi i częściowymi:
Rzadkie indeksy wybierają dokumenty do indeksowania wyłącznie na podstawie istnienia pola indeksowanego, a dla indeksów złożonych - istnienia pól indeksowanych.
Indeksy częściowe określają wpisy indeksu na podstawie określonego filtru. Filtr może zawierać pola inne niż klucze indeksu i może określać warunki inne niż tylko kontrola istnienia.
Indeks częściowy może jednak zaimplementować to samo zachowanie, co indeks rzadki
Na przykład:
db.contacts.createIndex(
{ name: 1 },
{ partialFilterExpression: { name: { $exists: true } } }
)
Uwaga: Nie można jednocześnie określić opcji częściowego filtra i opcji rzadkiej .