Indeksy w MongoDB - Instytut Informatyki Teoretycznej i Stosowanej
Transkrypt
Indeksy w MongoDB - Instytut Informatyki Teoretycznej i Stosowanej
Indeksy w MongoDB Technologie zarządzania treścią dr inż. Robert Perliński [email protected] Politechnika Częstochowska Instytut Informatyki Teoretycznej i Stosowanej 4 listopada 2016 Plan wykładu 1 Dane przestrzenne 2 Indeksy 3 Źródła Indeksy w MongoDB 2/32 Dane przestrzenne w MongoDB MongoDB udostępnia kilka indeksów przestrzennych i mechanizmów do pracy z danymi przestrzennymi. Format przechowywanych danych MongoDB obsługuje dwa rodzaje powierzchni dla danych przestrzennych: sferyczna kalkulacja geometryczne na sferze takiej jak Ziemia, używa się tutaj indeksów sferycznych 2d (ang. 2dsphere), przechowywanie danych w formacie obiektów GeoJSON, współrzędne w kolejności: długość, szerokość geograficzna, MongoDB używa systemu geodetycznego WGS84: http://spatialreference.org/ref/epsg/4326/ płaska obliczanie odległości na płaszczyźnie Euklidesowej, położenie zapisujemy jako para współrzędnych, używa się indeksów 2d (ang. 2d indexes). Indeksy w MongoDB 3/32 Dane lokalizacyjne Powierzchnia sferyczna: obiekty GeoJSON para współrzędnych na płaszczyźnie (MongoDB konwertuje dane do formatu GeoJSON. Powierzchnia płaska: tylko para współrzędnych na płaszczyźnie Format danych współrzędnych na płaszczyźnie używany był w MongoDB w wersji 2.4. Format przechowywał dane przestrzenne jako punkty w układzie współrzędnych na płaszczyźnie, np. [x, y]. Indeksy w MongoDB 4/32 Format GeoJSON GeoJSON Geoprzestrzenny format wymiany danych bazujący na JSON. Jest używany w zapytaniach przestrzennych. Obiekty GeoJSON używane są w kalkulacjach dotyczących powierzchni sferycznej. Specyfikacja GeoJSON dostępna na stronie: http://geojson.org/geojson-spec.html Dostępne są następujące obiekty GeoJSON: Point MultiPoint LineString MultiLineString Polygon MultiPolygon GeometryCollection Indeksy w MongoDB 5/32 Indeksy przestrzenne MongoDB usostępnia dwa rodzaje indeksów sepcjalnych do operowania na danych przestrzennych: indeksy 2d (ang. 2d indexes) kalkulacje używające geometrii na płaszczyźnie, używane dla danych umieszczonych na dwuwymiarowej płaszczyźnie. indeksy sferyczne 2d (ang. 2dsphere indexes) używane przy zapytaniach związanych z geometrią na sferze takiej jak Ziemia, wykorzystują format GeoJSON oraz (ze względu na wsteczną kompatybilność) pary współrzędnych na płaszczyźnie. Indeksy w MongoDB 6/32 Zapytania przestrzenne I Zapytania przestrzenne w MongoDB Zawieranie się zapytania o lokalizacje zawierające się całkowicie wewnątrz określonego wielokąta, używany jest tutaj operator $geoWithin, oba indeksy (2d i sferyczny 2d) wspierają zapytania dotyczące zawierania się, indeksy nie są wymagane ale zwiększają wydajność. Część wspólna, przecinanie się zapytania o lokalizacje, które przecinają (mają części wspóle) określoną geometrię, zapytania działają tylko na powierzchni sferycznej, używany jest operator $geoIntersects, możliwe wykorzystanie tylko indeksu sferycznego 2d. Indeksy w MongoDB 7/32 Zapytania przestrzenne II Zapytania przestrzenne w MongoDB Bliskość, sąsiedztwo zapytania o położenia będące blisko zadanych punktów, używany jest operator $near albo $nearSphere, wymagany jest indeks 2d albo sferyczny 2d. Indeksy w MongoDB 8/32 Restauracje - przykładowy dokument Baza restauracji zawiera położenia każdej z nich: { "_id" : ObjectId("5693cc5d9101bd8d7412fba4"), "adres" : { "numer" : "1007", "wspolrzedne" : [ -73.856077, 40.848447 ], "ulica" : "Morris Park Ave", "kod" : "10462" }, "dzielnica" : "Bronx", "jedzenie" : "Bakery", "oceny" : [ ...], "nazwa" : "Morris Park Bake Shop", "rest_id" : "30075445" } Indeksy w MongoDB 9/32 Operatory przestrzenne - $geoWithin Nazwy restauracji leżących wewnątrz podanego trójkąta (13km, 7km): db.resteuracje.find( { "adres.wspolrzedne": { $geoWithin: { $geometry: { type: "Polygon", coordinates:[ [ [ -73.856077, 40.848447 ], [ -73.856077+0.002, 40.848447 ], [ -73.856077+0.001, 40.848447+0.001 ], [ -73.856077, 40.848447 ] ] ] } } } }, { nazwa:1, _id:0 } ) { { { { { "nazwa" "nazwa" "nazwa" "nazwa" "nazwa" : : : : : Indeksy w MongoDB "Morris Park Bake Shop" } "Luke’S Lounge" } "15 Flavors " } "Nana’S Kitchen" } "New Fresco Toetillas Tommy’S Kitchen Inc" } 10/32 Operatory przestrzenne - $nearSphere Liczba restauracji leżących w odległości 500 m od podanego położenia. db.resteuracje.find( { "adres.wspolrzedne": { $nearSphere: [-73.856077, 40.848447], $maxDistance: 500/6371000 } } ).count() Dane o 3 restauracjach leżących w odległości 60 m od podanego położenia. db.resteuracje.find( { "adres.wspolrzedne": { $nearSphere: [-73.856077, 40.848447], $maxDistance: 60/6371000 } } ).pretty() Nazwy 5 restauracji leżących w odległości 100 m od podanego położenia. db.resteuracje.find( { "adres.wspolrzedne": { $nearSphere: [-73.856077, 40.848447], $maxDistance: 0.1/6371 } }, {nazwa:1,_id:0} ) { "nazwa" : "Morris Park Bake Shop" } { "nazwa" : "La Masa Restaurant" } { "nazwa" : "Patsy’S Pizzeria" } Indeksy w MongoDB { "nazwa" : "Luciano’S Pizza" } { "nazwa" : "Doyles Pub" } 11/32 Indeksy Indeksowanie pozwala na wysoką wydajność operacji odczytu dla często używanych zapytań. Indeksowanie w MongoDB: dostępne są różne typy indeksowania, mamy różne opcje konfiguracyjne, dostępny jest specjalny typ indeksowania. Bez indeksu, MongoDB musi przeprowadzić skanowanie kolekcji - trzeba sprawdzić każdy dokument, żeby określić czy spełnia on zapytanie czy nie. Jeśli istnieje odpowiedni indeks, to można go wykorzystać, żeby ogranicznyć liczbę dokumentów, które trzeba sprawdzić. Indeksy w MongoDB 12/32 Czym jest indeks Indeksy są strukturami b-drzew, które przechowują tylko małą część zbioru danych kolekcji w sposób ułatwiający przechodzenie po nich, przeszukiwanie ich. Indeksy: są strukturami B-drzew, przechowują wartości konkretnego pola albo zbioru pól, uporządkowane po wartości tego pola, uporządkowanie kolejności elementów pozwala na efektywne znajdowanie elementów z warunkiem równościowym oraz w warunkami określającymi zakres, dodatkowo możliwe jest zwrócenie uporzątkowaych wyników używając uporządkowania indeksu. Indeksy w MongoDB 13/32 Indeksy Indeksy w MongoDB: są podobne do indeksów w innych systemach baz danych, są definiowane na poziomie kolekcji, mogą być tworzone w oparciu o dowolne pole lub pod-pole dokumentu. Indeksy w MongoDB 14/32 Typy indeksów MongoDB udostępnia różne typy indeksów zależnie od: różnych typów danych, różnych zapytań. Indeks id: domyślny indeks określony na polu id, jest dostępny we wszystkich kolekcjach MongoDB, jeśli aplikacja nie określa wartości pola id, to zadba o to sterownik korzystając z wartości ObjectId, jest unikalny - nie pozwala na dodanie dwóch dokumentów z takim samym id. ObjectId Specjalny 12-bajtowy typ danych BSON gwarantujący unikalność w zakresie kolekcji. ObjectId jest generowany na bazie punktu czasowego (timestamp), ID maszyny, ID procesu i zwiększanego lokalnego licznika. Indeksy w MongoDB 15/32 Indeks na pojedynczym polu Opróczu indeksu id można tworzyć indeksy użytkownika w porządku rosnącym/malejącym bazujące na pojedynczym polu dokumentu. Dla pojedynczego pola kolejność sortowania (rosnąca/malejąca) po kluczu indeksu nie ma znaczenia. MongoDB może przechodzić po indeksie w obu kierunkach. Indeksy w MongoDB 16/32 Użycie indeksu w zapytaniu Indeksy w MongoDB 17/32 Indeks na wielu polach - złożony W MongoDB istnieje możliwość definiowania indeksów złożonych utworzonych na bazie wielu pól. Kolejność pól w definicji indeksu złożonego ma znaczenie. Jeśli indeks posiada dwa pola: {userid: 1, score: -1} to sortowanie odbywa się najpierw po userid i następnie (dla jednej wartości userid), po score. Dla indeksów złożonych kierunek sortowania (rosnąca/malejąca) decyduje o tym czy indeks może być wykorzystany przy operacji sortowania. Indeksy w MongoDB 18/32 Indeksy z wielu kluczy Indeksy z wielu kluczy (na bazie wielu kluczy): są w MongoDB używane do indeksowania zawartości tablic, pozwalają na wykorzystywanie zapytań zawierających odwołania do elementów tablicy, są tworzone automatycznie kiedy pole dla którego tworzony jest indeks zawiera tablicę - nie trzeba jawnie specyfikować typu indeksu, ich utworzenie powoduje utworzenie osobnego indeksu na każdym elemencie tej tablicy. Indeksy w MongoDB 19/32 Indeksy geoprzestrzenne i tekstowe Indeksy geoprzestrzenne MongoDB usostępnia dwa rodzaje indeksów sepcjalnych do operowania na danych przestrzennych: indeksy 2d (ang. 2d indexes) - używane dla danych umieszczonych na dwuwymiarowej płaszczyźnie, indeksy sferyczne 2d (ang. 2dsphere indexes) - używane przy zapytaniach związanych z geometrią na sferze takiej jak Ziemia. Indeksy tekstowe MongoDB udostępnia indeksy tekstowe, które wspomagają przeszukiwanie zawartości danych tekstowych. Nie zawierają słów przestankowych w danym języku, np. ”the”, ”a”, ”or”. Ograniczają się tylko do słów najważniejszych, podstawowych. Indeksy w MongoDB 20/32 Właściwości indeksów I Indeksy rozrzucone, rzadkie (ang. sparse indexes): własność rozrzucenia (ang. sparse) zapewnia, że indeks posiada wpisy tylko do tych dokumentów, w których jest indeksowane pole, dokumenty nie zawierające indeksowanego pola są w indeksie pomijane, zamiast posiadać wartość null. Indeksy częściowe (ang. partial indexes): indeksują tylko te dokumenty w kolekcji, które spełniają odpowiednie wyrażenie filtrujące, wymagają mniejszej przestrzeni dyskowej i mają większą wydajność zarówno przy tworzeniu jak i zarządzaniu nimi, oferują większą funkcjonalność niż indeksy rozrzucone - powinny być preferowane. Indeksy w MongoDB 21/32 Własności indeksów II Indeksy unikalne (ang. unique indexes): powodują odrzucanie powtórzonych wartości, jeśli pojawią się takie w dokumencie na polu związanym z indeksem, mają funkcjonalność wymienialną, zamienną z innymi własnościami indeksów, można stworzyć np. indeks będący unikalnym i rozrzuconym. Indeksy TTL (ang. TTL indekses): specjalne indeksy w MongoDB pozwalające na automatyczne usunięcie dokumentów z kolekcji po upływie określonego czasu, dobre rozwiązanie dla pewnego rodzaju informacji, np. generowanych automatycznie przez zdarzenia systemowe (logi, informacje o sesji). Indeksy w MongoDB 22/32 Zapytania ”pokryte” indeksami Jeśli kryteria zapytania i projekcji uzwględniają tylko zindeksowane pola, to MongoDB zwraca wyniki bezpośrednio z indesku, bez przeszukiwania dokumentów. Jest to bardzo efektywne. Indeksy w MongoDB 23/32 Lista utworzonych indeksów Polecenie db.kolekcja.getIndexes() zwraca tablicę dokumentów zawierających listę indeksów kolekcji wraz z ich opisem. Opis indeksu zawiera jego klucze i opcje jakich użyto przy jego tworzeniu. db.osoby.getIndexes() Wynik polecenia, lista utworzonych indeksów: [ { "v" : 1, "key" : { " id" : 1 }, "ns" : "test.osoby", "name" : " id " }, { "v" : 1, "key" : { "wiek" : 1 }, "ns" : "test.osoby", "name" : "wiek 1" } ] Indeksy w MongoDB 24/32 Tworzenie indeksów db.kolekcja.createIndex(klucze, opcje) - tworzy indeks na kolekcji. Parametr klucze jest dokumentem składającym sie z par pole:wartość. pole określa nazwę klucza dla indeksu. wartość określa typ indeksu: 1 - kolejność rosnąca, -1 - kolejność malejąca. Paramet opcje nie jest obowiązkowy. Określa opcje tworzenia indeksu. Są opcje wspólne dla wszystkich indeksów. Są również opcje dotyczące tylko wybranych ich typów. Indeksy w MongoDB 25/32 Najważniejsze opcje tworzenia indeksów db.kolekcja.createIndex(klucze, opcje) Wszystkie wymienione opcje tworzenia indeksów nie są obowiązkowe. unique - (wartość logiczna) - tworzy indeks, który jest unikalny; kolekcja nie zaakceptuje dodawania dokumentów, w których klucz lub klucze mają wartości występujące już w indeksie, name - (ciąg znakowy) - nazwa indeksu, jeśli nie poda się nazwy MongoDB utworzy nazwę łącząc nazwy indeksowanych pól z wartością określającą porządek sortowania, sparse - (wartość logiczna) - tworzy indeks, który zawiera tylko odwołania do istniejących dokumentów, które zawierają pola, na których utworzono indeks, v - (wersja indeksu) - określa numer wersji indeksu, domyślnie zależne od wersji MongoDB, expireAfterSeconds - (wartość całkowita) - dla indeksów TTL określa jak długo w sekundach będą przechowywane dokumenty w kolekcji, background - (wartość logiczna) - określa czy tworzenie indeksu ma się odbywać ”w tle”, domyślnie false. Indeksy w MongoDB 26/32 Tworzenie indeksów Indeks złożony zbudowany w oparciu o dwa pola: db.osoby.createIndex({stanKonta:1, wiek:-1}) Tworzy indeks z wielu kluczy, pole przyjaciele jest tablicą: db.osoby.createIndex({przyjaciele:1}) Tworzy indeks tekstowy w oparciu o pole adres: db.osoby.createIndex({adres: "text"}) Wymaga aby przeszukiwanie tekstowe byłą włączone (domyślnie w 2.6). W wersji 2.4 można samodzielnie włączyć: mongod --setParameter textSearchEnabled=true Kolekcja może mieć co najwyżej jeden indeks tekstowy. Tworzy indeks przestrzenny na powierzchni 2d, pole adres.wspolrzedne: db.restauracje.createIndex({"adres.wspolrzedne":"2d"}) Indeksy w MongoDB 27/32 Usuwanie indeksów Usuwanie indeksu db.kolekcja.dropIndex(index) usuwa określony index z kolekcji, metoda dropIndex() wykorzystuje metodę dropIndexes(), db.collection.dropIndexes() usuwa wszystkie indeksy z kolekcji z wyjątkiem id, nie można usunąć domyślnego indeksu utworzonego na polu id, parametr index jest napisem (nazwa indeksu) lub dokumentem (specyfikacja indeksu), określa indeks do usunięcia, usuwanie indeksów tekstowych wymaga podania nazwy indeksu, przykład: db.osoby.dropIndex({wiek:1}) ALBO db.osoby.dropIndex("wiek 1") Indeksy w MongoDB 28/32 Użycie indeksu I Wykorzystanie indeksu zwiększa szybkość odczytu danych. Metody cursor.explain("executionStats") oraz db.collection.explain("executionStats") udostępniają statystyki wydajnościowe wykonywanych zapytań. Przykład wykorzystania indeksu dla bazy 50 osób (db.osoby.findOne()): { " id" : "566893bd2ae04f8923cb23c3", "index" : 0, "zatrudniony" : true, "stanKonta" : 1833.19, "wiek" : 21, "oczy" : "niebieskie", "nazwa" : { "imie" : "Keri", "nazwisko" : "Hubbard" }, "firma" : "FUTURIS", "email" : "[email protected]", "telefon" : "+1 (887) 496-3887", "adres" : "117 Boynton Place, Gwynn, Wisconsin, 3666", "przyjaciele" : [ ... ], "ulubionyOwoc" : "jabłka" } Indeksy w MongoDB 29/32 Użycie indeksu II zapytanie: db.osoby.find().count() zwraca wartość 50, zapytanie: db.osoby.find({wiek:{$gte: 30, $lte:40 }}).count() zwraca wartość 13, zapytanie: db.osoby.find({wiek:{$gte: 30, $lte:40 }} ).explain("executionStats") zwraca: { "allPlans" : [ { "cursor" : "BasicCursor", "n" : 13, "nscannedObjects" : 50, "nscanned" : 50, "indexBounds" : { } } ], ... } Indeksy w MongoDB 30/32 Użycie indeksu III zapytanie: db.osoby.createIndex({wiek:1}) - tworzy indeks na polu wiek, zapytanie: db.osoby.find({wiek:{$gte: 30, $lte:40 }}).count() zwraca wartość 13, zapytanie: db.osoby.find({wiek:{$gte: 30, $lte:40 }} ).explain("executionStats") zwraca: { "allPlans" : [ { "cursor" : "BtreeCursor wiek_1", "n" : 13, "nscannedObjects" : 13, "nscanned" : 13, "indexBounds" : { "wiek" : [ [ 30, 40 ] ] } } ], ... } Indeksy w MongoDB 31/32 Źródła W wykładzie wykorzystano materiały: Pramod J. Sadlage, Martin Folwer, NoSQL Kompendium wiedzy, Helion, 2015 http://json.org/ http://bsonspec.org/ https://docs.mongodb.org/ecosystem/tools/ administration-interfaces/ http://geojson.org/geojson-spec.html https://docs.mongodb.org/manual/indexes/ Indeksy w MongoDB 32/32