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