9 rodzajów operatorów Mongodb, które musisz znać

Opublikowany: 2022-09-09

W każdej firmie dane są Twoim największym atutem. Analizując dane, możesz podejmować decyzje dotyczące trendów klientów i przewidywania zachowań. Zwiększa to rentowność biznesu i efektywne podejmowanie decyzji.

Bez oprogramowania bazodanowego proste zadanie, takie jak znalezienie średniej ze wszystkich wartości w systemie pełnym rekordów, byłoby nużące. Na szczęście bazy danych ułatwiają i przyspieszają analizę danych dzięki funkcjom i operatorom.

Ten artykuł rzuci trochę światła na operatory używane w oprogramowaniu bazodanowym MongoDB.

Czym są operatory MongoDB?

MongoDB to oprogramowanie bazy danych NoSQL, które zarządza informacjami zorientowanymi na dokumenty.

Jedną z kluczowych cech MongoDB jest jego szybkość. Aby szybciej zwracać zapytania, MongoDB może używać operatorów do wykonywania określonych funkcji.

Operatory to specjalne symbole, które pomagają kompilatorom wykonywać zadania matematyczne lub logiczne. MongoDB oferuje kilka typów operatorów do interakcji z bazą danych.

Typy operatorów MongoDB

Istnieje dziewięć typów operatorów, z których każdy ma swoją nazwę. Na przykład operatory logiczne używają operacji logicznych. Aby je wykonać, musisz użyć określonego słowa kluczowego i postępować zgodnie ze składnią. Jednak są one dość łatwe do naśladowania!

Pod koniec artykułu będziesz mógł nauczyć się podstaw każdego operatora i jego funkcji.

Operatory logiczne

Operatory logiczne są często używane do filtrowania danych na podstawie podanych warunków. Pozwalają również na ocenę wielu warunków, które omówimy bardziej szczegółowo.

Poniżej znajduje się kilka operatorów logicznych, których możesz użyć:

$i

Warunek „i” wykonuje logiczną operację „i” na tablicy dwóch lub więcej wyrażeń. Wybiera dokumenty, w których spełnione są wszystkie warunki wyrażeń.

To jest standardowa składnia wyrażenia $and :

 { $and: [ { <expression1> }, { <expression2> }, ... , { <expressionN> } ] } Na przykład, jeśli chcemy wybrać dokumenty, w których cena wynosi 10 zł, a ilość jest mniejsza niż 15, możemy wprowadzić następujące zapytanie:
 db.inventory.find( { $and: [ { quantity: { $lt: 15 } }, { price: 10 } ] } )

$lub

Warunek „lub” wykonuje logiczną operację „lub” na tablicy dwóch lub więcej wyrażeń. Wybiera dokumenty, w których przynajmniej jedno z wyrażeń jest prawdziwe.

To jest standardowa składnia wyrażenia $or :

 { $or: [ { <expression1> }, { <expression2> }, ... , { <expressionN> } ] }.

Na przykład, jeśli chcemy wybrać dokumenty, w których cena wynosi 10 zł lub ilość jest mniejsza niż 15, możemy wprowadzić następujące zapytanie:

 db.inventory.find( { $or: [ { quantity: { $lt: 15 } }, { price: 10 } ] } )

Nie musimy ograniczać wyrażenia do dwóch kryteriów — możemy dodać więcej. Na przykład poniższe zapytanie wybiera te dokumenty, w których cena wynosi 10 zł, ilość jest mniejsza niż 15 lub tag jest nieruchomy:

 db.inventory.find( { $or: [ { quantity: { $lt: 15 } }, { price: 10 }, { tag: stationary }] } )

Podczas uruchamiania tych klauzul MongoDB wykonuje skanowanie kolekcji lub skanowanie indeksu. Jeśli wszystkie indeksy obsługują klauzule, MongoDB używa indeksów do sprawdzania wyrażenia $or . W przeciwnym razie zamiast tego używa skanowania kolekcji.

Ale jeśli chcesz przetestować kryteria w tym samym polu, możesz użyć operatora $in zamiast operatora $or . Na przykład, jeśli potrzebujesz kolekcji dokumentów, w której ilość wynosi 10 lub 20, może być konieczne uruchomienie poniższej kwerendy $in :

 db.inventory.find ( { quantity: { $in: [20, 50] } } )

Więcej o operatorze $in omówimy później.

$nor

Ten operator wykonuje logiczną operację „nor” na tablicy przy użyciu jednego lub więcej wyrażeń. Następnie wybiera dokumenty, które nie spełniają wyrażeń zapytania. Mówiąc prościej, działa odwrotnie do warunku $or .

Oto ogólna składnia:

 { $nor: [ { <expression1> }, { <expression2> }, ... { <expressionN> } ] }

Rozważmy następujące zapytanie:

 db.inventory.find( { $nor: [ { price: 3.99 }, { sale: true } ] } )

To zapytanie wybiera dokumenty, które zawierają:

  • wartość pola ceny nie równa 3,99 USD i wartość sprzedaży nie równa true; lub
  • wartość pola ceny nie równa 3,99 USD oraz puste lub nieobecne pole sprzedaży; lub
  • brak pola ceny, a pole sprzedaży nie jest równe prawdzie; lub
  • ani pole ceny, ani pole sprzedaży nie są wypełnione ani obecne.

$nie

Ten operator wykonuje logiczną operację „nie” na tablicy dla określonego wyrażenia. Następnie wybiera dokumenty, które nie pasują do wyrażeń zapytania. Obejmuje to dokumenty, które nie zawierają tego pola.

Oto ogólna składnia:

 { field: { $not: { <operator-expression> } } }

Na przykład weź następujące zapytanie:

 db.inventory.find( { price: { $not: { $lt: 3.99 } } } )

To zapytanie wybierze te dokumenty, które zawierają:

  • pole ceny o wartości większej lub równej 3,99 USD; oraz
  • pole ceny jest puste lub nie istnieje.

Operatory porównania

Operatorów porównania można używać do porównywania wartości w jednym lub kilku dokumentach.

Poniżej znajduje się przykładowy kod prostej kolekcji inwentarza dla sklepu supermarketu:

 { _id: 1, item: { name: "apple", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] }, { _id: 2, item: { name: "banana", code: "123" }, qty: 20, tags: [ "B" ] }, { _id: 3, item: { name: "spinach", code: "456" }, qty: 25, tags: [ "A", "B" ] }, { _id: 4, item: { name: "lentils", code: "456" }, qty: 30, tags: [ "B", "A" ] }, { _id: 5, item: { name: "pears", code: "000" }, qty: 20, tags: [ [ "A", "B" ], "C" ] }, { _id: 6, item: { name: "strawberry", code: "123" }, tags: [ "B" ] }

Użyjemy tego przykładu, szczegółowo opisując każdy operator porównania.

Równe ($eq)

Ten operator dopasowuje wartości, które są równe podanej wartości:

 { <field>: { $eq: <value> } }

Na przykład, jeśli chcemy pobrać konkretny dokument ze zbioru magazynowego o dokładnej wartości ilości „20”, wpisujemy następujące polecenie:

 db.inventory.find( { qty: { $eq: 20 } } )

Zapytanie zwróci następujące informacje:

 { _id: 2, item: { name: "banana", code: "123" }, qty: 20, tags: [ "B" ] }, { _id: 5, item: { name: "pears", code: "000" }, qty: 20, tags: [ [ "A", "B" ], "C" ] }

Większe niż ($gt)

Ten operator pasuje, jeśli wartości są większe niż podana wartość:

 { field: { $gt: value } }

W tym przykładzie pobieramy dokumenty, których ilość jest większa niż 15:

 db.inventory.find({"qty": { $gt: 15}})

Zapytanie zwróci następujące informacje:

 { _id: 2, item: { name: "banana", code: "123" }, qty: 20, tags: [ "B" ] } { _id: 3, item: { name: "spinach", code: "456" }, qty: 25, tags: [ "A", "B" ] } { _id: 4, item: { name: "lentils", code: "456" }, qty: 30, tags: [ "B", "A" ] } { _id: 5, item: { name: "pears", code: "000" }, qty: 20, tags: [ [ "A", "B" ], "C" ] }

Mniej niż (lt)

Ten operator pasuje, jeśli wartości są mniejsze niż podana wartość:

 { field: { $lt: value } }

Znajdźmy dokumenty w ilości mniejszej niż 25:

 db.inventory.find({"qty": { $lt: 25}})

Zapytanie zwróci następujące informacje:

 { _id: 1, item: { name: "apple", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] } { _id: 2, item: { name: "banana", code: "123" }, qty: 20, tags: [ "B" ] } { _id: 5, item: { name: "pears", code: "000" }, qty: 20, tags: [ [ "A", "B" ], "C" ] }

Większe lub równe ($gte)

Ten operator pasuje, gdy wartości są większe lub równe podanej wartości:

 { field: { $gte: value } }

W tym przykładzie pobieramy dokumenty, których ilość jest większa lub równa 25:

 db.inventory.find({"qty": { $gte: 25}})

To zapytanie zwróci następujące informacje:

 { _id: 3, item: { name: "spinach", code: "456" }, qty: 25, tags: [ "A", "B" ] } { _id: 4, item: { name: "lentils", code: "456" }, qty: 30, tags: [ "B", "A" ] }

Mniejsze lub równe ($lte)

Ten operator pasuje tylko wtedy, gdy wartości są mniejsze lub równe podanej wartości:

 { field: { $lte: value } }

Znajdźmy dokumenty z ilością mniejszą lub równą 25.

 db.inventory.find({"qty": { $lte: 25}})

Możemy oczekiwać, że to zapytanie zwróci następujące informacje:

 { _id: 1, item: { name: "apple", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] } { _id: 2, item: { name: "banana", code: "123" }, qty: 20, tags: [ "B" ] } { _id: 3, item: { name: "spinach", code: "456" }, qty: 25, tags: [ "A", "B" ] } { _id: 5, item: { name: "pears", code: "000" }, qty: 20, tags: [ [ "A", "B" ], "C" ] }

W (w dolarach)

Ten operator zwraca dokumenty, które pasują do określonych wartości:

 { field: { $in: [<value1>, <value2>, ... <valueN> ] } }

Wartość pola jest równa dowolnej wartości w określonej tablicy. Aby np. pobrać dokumenty o wartościach „30” i „15” w kolekcji inwentarzowej, należy:

 db.collection.find({ "qty": { $in: [30, 15]}})

Dane wyjściowe byłyby następujące:

 { _id: 1, item: { name: "apple", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] } { _id: 4, item: { name: "lentils", code: "456" }, qty: 30, tags: [ "B", "A" ] }
Zapytanie jest uruchamiane w powłoce MongoDB.

Nie w (dziew.$)

Ten operator zwraca dokumenty, które nie pasują do podanych wartości. Oto podstawowa składnia operatora $nin :

 { field: { $nin: [ <value1>, <value2> ... <valueN> ]

$nin wybiera dokumenty, w których:

  • wartość pola nie znajduje się w określonej tablicy; lub
  • pole nie istnieje.

Jeśli pole zawiera tablice, wybierze tablice, w których nie ma żadnego elementu określonego w sekcji wartości. Na przykład chcemy wybrać te dokumenty, których ilość nie jest równa ani 20, ani 15.

Dodatkowo dopasowuje również dokumenty, które nie mają pola ilościowego:

 db.collection.find({ "qty": { $nin: [ 20, 15 ]}}, {_id: 0})

Dane wyjściowe byłyby następujące:

 { _id: 3, item: { name: "spinach", code: "456" }, qty: 25, tags: [ "A", "B" ] } { _id: 4, item: { name: "lentils", code: "456" }, qty: 30, tags: [ "B", "A" ] } { _id: 6, item: { name: "strawberry", code: "123" }, tags: [ "B" ] }

Nie równe ($ne)

Operator $ne zwraca dokumenty, w których podana wartość nie jest równa:

 { $ne: value } }

Na przykład, powiedzmy, że chcemy wybrać wszystkie dokumenty, których ilość nie jest równa 20:

 db.inventory.find( { qty: { $ne: 20 } } )

Dane wyjściowe byłyby następujące:

 { _id: 1, item: { name: "apple", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] } { _id: 3, item: { name: "spinach", code: "456" }, qty: 25, tags: [ "A", "B" ] } { _id: 4, item: { name: "lentils", code: "456" }, qty: 30, tags: [ "B", "A" ] } { _id: 6, item: { name: "strawberry", code: "123" }, tags: [ "B" ] }

Z powyższego wyniku widzimy, że zapytanie wybierze dokumenty, które nie mają pola ilościowego.

Operatory elementów

Operatory zapytań o elementy mogą identyfikować dokumenty za pomocą pól dokumentu. Operatory elementów składają się z $exist i $type .

$istnieje

Ten operator dopasowuje dokumenty, które mają określone pole. Ten operator ma wartość logiczną, która może być true lub false .

Jeśli zostanie określony jako true , dopasowuje dokumenty zawierające to pole, w tym dokumenty, w których wartość pola jest równa null. Jeśli <boolean> ma wartość false , zapytanie zwraca tylko dokumenty, które nie zawierają tego pola.

Oto standardowa składnia:

 { field: { $exists: <boolean> } }

Weźmy przykład, w którym mamy zbiór danych dla tablicy o nazwie „bagofmarbles”, gdzie każda torba zawiera kulki o różnych kolorach:

 { red: 5, green: 5, blue: null } { red: 3, green: null, blue: 8 } { red: null, green: 3, blue: 9 } { red: 1, green: 2, blue: 3 } { red: 2, blue: 5 } { red: 3, green: 2 } { red: 4 } { green: 2, blue: 4 } { green: 2 } { blue: 6 }

Powiedzmy, że potrzebujemy zapytania, które zwróci tylko te torby, w których istnieją czerwone kulki. Oznacza to, że musielibyśmy wprowadzić wartość logiczną jako true . Spójrzmy:

 db.bagofmarbles.find( { red: { $exists: true } } )

Wyniki składałyby się z tych dokumentów, które zawierają pole „red”, nawet jeśli wartość byłaby null . Nie zawierałby jednak dokumentów, w których pole „czerwone” nawet nie istniało:

 { red: 5, green: 5, blue: null } { red: 3, green: null, blue: 8 } { red: null, green: 3, blue: 9 } { red: 1, green: 2, blue: 3 } { red: 2, blue: 5 } { red: 3, green: 2 } { red: 4 }

Gdybyśmy chcieli tylko tych worków, w których czerwone kulki nawet nie istnieją jako pole, możemy wprowadzić poniższe zapytanie:

 db.bagofmarbles.find( { red: { $exists: false} }

Wyniki składałyby się z tych dokumentów, które nie zawierają pola „czerwony”:

 { green: 2, blue: 4 } { green: 2 } { blue: 6 }

$typ

Ten operator dopasowuje dokumenty zgodnie z określonym typem pola. Jest to przydatne, gdy masz bardzo nieustrukturyzowane dane lub gdy typy danych nie są przewidywalne. Te typy pól są określonymi typami BSON i można je zdefiniować za pomocą numeru typu lub aliasu.

To jest ogólna składnia dla $type :

 { field: { $type: <BSON type> } }

Załóżmy, że mamy książkę adresową zawierającą poniższe dokumenty:

 db={ addressBook: [ { "_id": 1, address: "2100 Jupiter Spot", zipCode: "9036325" }, { "_id": 2, address: "25 Moon Place", zipCode: 26237 }, { "_id": 3, address: "2324 Neptune Ring", zipCode: NumberLong(77622222) }, { "_id": 4, address: "33 Saturns Moon", zipCode: NumberInt(117) }, { "_id": 5, address: "1044 Venus Lane", zipCode: [ "99883637232", "73488976234" ] } ] }

Obserwując powyższe dokumenty, kod pocztowy ma różne typy danych. Obejmuje to wartości długie, podwójne, całkowite i łańcuchowe.

Jeśli chcemy tylko tych dokumentów, które mają określony typ danych jako kod pocztowy — weźmy ciąg znaków dla tego wystąpienia — musielibyśmy wprowadzić do kompilatora następujące zapytanie:

 db.addressBook.find({ "zipCode": { $type: "string" } })

Spowoduje to zwrócenie następujących dokumentów:

 [ { "_id": 1, "address": "2100 Jupiter Spot", "zipCode": "9036325" }, { "_id": 5, "address": "1044 Venus Lane", "zipCode": [ "99883637232", "73488976234" ] } ]
Powyższe zapytanie działa w powłoce MongoDB.

Dodatkowo istnieje typ „number”, który zawiera wszystkie wartości long, integer lub double jako tablicę zawierającą element określonego typu:

 db.addressBook.find( { "zipCode" : { $type : "number" } } )

Wyjście:

 [ { "_id": 2, address: "25 Moon Place", zipCode: 26237 }, { "_id": 3, address: "2324 Neptune Ring", zipCode: NumberLong(77622222) }, { "_id": 4, address: "33 Saturns Moon", zipCode: NumberInt(117) } ]

Jeśli dokumenty mają typ pola tablicy, operator $type zwraca dokumenty, w których co najmniej jeden element tablicy odpowiada typowi przekazanemu do operatora.

Operatory tablicowe

MongoDB składa się również z operatorów tablicowych, służących do wyszukiwania dokumentów zawierających tablice.

Istnieją trzy główne operatory: $all , $elemMatch i $size . Omówimy każdy z nich szczegółowo poniżej.

$wszystkie

Operator $all wybiera dokumenty, w których wartością pola jest tablica zawierająca określone elementy:

 { : { $all: [ <value1> , <value2> ... ] } }

Załóżmy na przykład, że mamy kolekcję dokumentów dla sklepu odzieżowego, z następującymi w inwentarzu.

 { _id: ObjectId("5234cc89687ea597eabee675"), code: "shirt", tags: [ "sale", "shirt", "button", "y2k", "casual" ], qty: [ { size: "S", num: 10, color: "blue" }, { size: "M", num: 45, color: "blue" }, { size: "L", num: 100, color: "green" } ] }, { _id: ObjectId("5234cc8a687ea597eabee676"), code: "pant", tags: [ "y2k", "trendy", "shine" ], qty: [ { size: "6", num: 100, color: "green" }, { size: "6", num: 50, color: "blue" }, { size: "8", num: 100, color: "brown" } ] }, { _id: ObjectId("5234ccb7687ea597eabee677"), code: "pant2", tags: [ "trendy", "shine" ], qty: [ { size: "S", num: 10, color: "blue" }, { size: "M", num: 100, color: "blue" }, { size: "L", num: 100, color: "green" } ] }, { _id: ObjectId("52350353b2eff1353b349de9"), code: "shirt2", tags: [ "y2k", "trendy" ], qty: [ { size: "M", num: 100, color: "green" } ] }

Chcielibyśmy pobrać wszelkie dokumenty (w tym przypadku ubrania) z inwentarza, które są powiązane z tagami „trendy” i „y2k”. Poniższe zapytanie używa operatora $all , gdzie wartością pola tags jest tablica zawierająca elementy „y2k” i „trendy”:

 db.inventory.find( { tags: { $all: [ "y2k", "trendy" ] } } )

Powyższe zapytanie zwraca co następuje:

 { _id: ObjectId("5234cc8a687ea597eabee676"), code: "pant", tags: [ "y2k", "trendy", "shine" ], qty: [ { size: "6", num: 100, color: "green" }, { size: "6", num: 50, color: "blue" }, { size: "8", num: 100, color: "brown" } ] } { _id: ObjectId("52350353b2eff1353b349de9"), code: "shirt2", tags: [ "y2k", "trendy" ], qty: [ { size: "M", num: 100, color: "green" } ] }
Powyższe zapytanie działa w powłoce MongoDB.

Z powyższego przykładu dowiadujemy się również, że operator $all po prostu wykonuje tę samą funkcję, co operacja $and .

Alternatywnie moglibyśmy użyć poniższego zapytania, które dałoby podobny wynik do powyższego:

 db.collection.find({ $and: [ { tags: "y2k" }, { tags: "trendy" } ] })
Powyższe zapytanie działa w powłoce MongoDB.

$elemMatch

Operator $elemMatch dopasowuje dokumenty, które zawierają pole tablicy z co najmniej jednym elementem, który spełnia wszystkie określone kryteria zapytania:

 { : { $elemMatch: { <query1>, <query2>, ... } } }

Chociaż możemy używać operatorów porównania, takich jak $lte i $gte , jeśli określimy tylko jeden warunek zapytania wewnątrz $elemMatch i nie używamy operatorów $not ani $ne , użycie $elemMatch można pominąć, ponieważ zasadniczo tę samą funkcję.

Jest jeszcze kilka rzeczy, o których należy pamiętać podczas korzystania z tego operatora, głównie:

  • Nie możesz określić wyrażenia $ $where w operacji $elemMatch .
  • Nie możesz określić wyrażenia zapytania $text w operacji $elemMatch .

Na przykład w kolekcji wyników uczniów mamy następujące dokumenty:

 { _id: 1, results: [ 92, 89, 98 ] } { _id: 2, results: [ 85, 99, 99 ] }

Poniższe zapytanie dopasowuje tylko te dokumenty, w których tablica wyników zawiera co najmniej jeden element, który jest zarówno większy lub równy 90, jak i mniejszy niż 95:

 db.studentresults.find( { results: { $elemMatch: { $gte: 90, $lt: 95 } } })

Nasze zapytanie zwraca następujący dokument, ponieważ element 92 jest zarówno większy lub równy 90, jak i mniejszy niż 95:

 { "_id" : 1, "results" :[ 92, 89, 98 ] }

$rozmiar

Operator $size zwraca te dokumenty, w których rozmiar tablicy odpowiada liczbie elementów określonej w argumencie:

 { field: { $size: value } }

Oto przykład:

 db.collection.find( { field: { $size: 2 } });

Spowoduje to zwrócenie wszystkich dokumentów z określonej kolekcji, w której pole jest tablicą z 2 elementami: { field: [ orange, apple] } i { field: [ blue, red] } , ale nie { field: blue} lub { field: [ raspberry, lemon, grapefruit ] } .

Jednak chociaż możemy wprowadzić konkretną wartość jako rozmiar, nie możemy określić zakresów wartości jako rozmiaru.

Operatorzy geoprzestrzenni

MongoDB umożliwia przechowywanie danych geoprzestrzennych w postaci typów GeoJSON. GeoJSON to format o otwartym standardzie oparty na notacji obiektów JavaScript, który może reprezentować cechy geograficzne i obsługiwać atrybuty nieprzestrzenne. W tym artykule omówimy dwa typy operatorów geoprzestrzennych: specyfikatory geometrii i selektory zapytań.

$geometria

Ten operator wymienia geometrię GeoJSON do użytku z następującymi geoprzestrzennymi operatorami zapytań: $geoIntersects , $geoWithin , $nearSphere i $near . $geometry wykorzystuje EPSG:4326 jako domyślny układ odniesienia współrzędnych (CRS).

Aby wspomnieć o obiektach GeoJSON z domyślnym CRS, możesz wykorzystać następujący fragment kodu dla $geometry :

 $geometry: { type: "<GeoJSON object type>", coordinates: [ <coordinates> ] }

Aby wspomnieć o jednopierścieniowym wieloboku GeoJSON z dostosowanym CRS MongoDB, możesz użyć następującego fragmentu kodu (możesz go użyć tylko dla $geoWithin i $geoIntersects ):

 $geometry: { type: "Polygon", coordinates: [ <coordinates> ], crs: { type: "name", properties: { name: "urn:x-mongodb:crs:strictwinding:EPSG:4326" } } }

$wielokąt

Operator $polygon może służyć do określenia wielokąta dla zapytania geoprzestrzennego $geoWithin na starszych parach współrzędnych. To zapytanie zwróci wtedy pary, które mieszczą się w granicach wielokąta. Jednak $polygon nie będzie pytać o żadne obiekty GeoJSON. Aby zdefiniować wielokąt, musisz określić tablicę punktów współrzędnych w następujący sposób:

 { : { $geoWithin: { $polygon: [ [ <x1> , <y1> ], [ <x2> , <y2> ], [ <x3> , <y3> ], ... ] } } }

Tutaj ostatni punkt jest niejawnie połączony z pierwszym. Możesz wymienić tyle punktów lub stron, ile chcesz.

Na przykład następujące zapytanie zwróci wszystkie dokumenty, których współrzędne istnieją w wieloboku zdefiniowanym przez [0,0], [1,5] i [3,3]:

 db.places.find( { loc: { $geoWithin: { $polygon: [ [ 0 , 0 ], [ 1 , 5 ], [ 3 , 3 ] ] } } } )

$geoWithin

Ten operator może być używany do wybierania dokumentów z danymi geoprzestrzennymi, które są całkowicie zawarte w określonym kształcie. Określony kształt może być wielokątem GeoJSON, wielokątem GeoJSON (z wieloma lub pojedynczym pierścieniem) lub kształtem, który można zdefiniować za pomocą starszych par współrzędnych.

Operator $geoWithin operatora $geometry , aby wspomnieć o obiekcie GeoJSON.

Aby wymienić wielokąty lub wielokąty GeoJSON za pośrednictwem domyślnego systemu odniesienia za pomocą współrzędnych (CRS), możesz użyć składni wymienionej poniżej:

 { : { $geoWithin: { $geometry: { type: <"Polygon" or "MultiPolygon"> , coordinates: [ <coordinates> ] } } } }

W przypadku zapytań $geoWithin , które wymieniają geometrie GeoJSON z obszarami większymi niż pojedyncza półkula, użycie domyślnego CRS doprowadziłoby do zapytań o geometrie uzupełniające.

Aby wspomnieć o jednopierścieniowym wieloboku GeoJSON z niestandardowym CRS MongoDB, możesz wykorzystać prototyp wspomniany poniżej w wyrażeniu $geometry :

 { : { $geoWithin: { $geometry: { type: "Polygon" , coordinates: [ <coordinates> ], crs: { type: "name", properties: { name: "urn:x-mongodb:crs:strictwinding:EPSG:4326" } } } } } }

Poniższy przykład wybiera wszystkie dane loc, które istnieją w całości w obrębie wielokąta GeoJSON, przy czym powierzchnia wielokąta jest mniejsza niż powierzchnia pojedynczej półkuli:

 db.places.find( { loc: { $geoWithin: { $geometry: { type : "Polygon" , coordinates: [ [ [ 0, 0 ], [ 3, 6 ], [ 6, 1 ], [ 0, 0 ] ] ] } } } } )

$pudełko

Możesz użyć $box aby określić prostokąt dla zapytania geoprzestrzennego $geoWithin , aby dostarczyć dokumenty, które znajdują się w granicach prostokąta, zgodnie z ich danymi lokalizacji opartymi na punktach. Kiedy użyjesz $geoWithin z $box , otrzymasz dokumenty oparte na współrzędnych zapytania. W tym scenariuszu $geoWithin nie będzie wysyłać zapytań o żadne kształty GeoJSON.

Aby wykorzystać operator $box , musisz wspomnieć o prawym górnym i lewym dolnym rogu prostokąta w obiekcie tablicy:

 { <location field> : { $geoWithin: { $box: [ [ <bottom left coordinates> ], [ <upper right coordinates> ] ] } } }

Wspomniane zapytanie obliczy odległość przy użyciu płaskiej (płaskiej) geometrii. Poniższe zapytanie zwróci wszystkie dokumenty, które znajdują się w polu o punktach: [0,0], [0,30], [30,0], [30,30]:

 db.places.find ( { loc: { $geoWithin: { $box: [ [ 0,0 ], [ 30,30 ] ] } } } )

$bliskoSfera

Możesz użyć $nearSphere , aby wspomnieć o punkcie, dla którego zapytanie geoprzestrzenne zwraca dokumenty od najbliższego do najdalszego.

MongoDB używa geometrii sferycznej do obliczania odległości dla $nearSphere . Będzie potrzebował indeksu geoprzestrzennego w następujący sposób:

  1. Indeks 2d dla danych lokalizacji opisanych jako starsze pary współrzędnych. Aby wykorzystać indeks 2d na punktach GeoJSON, musisz wygenerować indeks w polu współrzędnych obiektu GeoJSON.
  2. Indeks 2dsphere dla danych o lokalizacji opisanych jako punkty GeoJSON.

Aby wspomnieć o punkcie GeoJSON, możesz wykorzystać następującą składnię:

 { $nearSphere: { $geometry: { type : "Point", coordinates : [ <longitude>, <latitude> ] }, $minDistance: <distance in meters>, $maxDistance: <distance in meters> } }

W tym $minDistance i $maxDistance są opcjonalne. $minDistance może ograniczyć wyniki do tych dokumentów, które znajdują się co najmniej w określonej odległości od środka. Możesz użyć $maxDistance dla obu indeksów.

Rozważmy teraz zbiór „miejsc”, który składa się z dokumentów z polem lokalizacji, które ma indeks 2dsphere. Poniższy przykład zwróci punkty, których lokalizacja wynosi co najmniej 2000 metrów i co najwyżej 6000 metrów od wybranego punktu, uporządkowane od najbliższego do najdalszego:

 db.places.find( { location: { $nearSphere: { $geometry: { type : "Point", coordinates : [ -43.9532, 50.32 ] }, $minDistance: 2000, $maxDistance: 6000 } } } )

$geoIntersects

Operator $geoIntersects pozwala wybrać dokumenty, których dane geoprzestrzenne przecinają się z określonym obiektem GeoJSON (tj. gdzie zbieżność określonego obiektu i danych nie jest pusta). Wykorzystuje operator $geometry do określenia obiektu GeoJSON.

Aby wymienić wielokąty lub wielokąty GeoJSON za pomocą domyślnego układu odniesienia współrzędnych (CRS), możesz użyć następującej składni:

 { <location field>: { $geoIntersects: { $geometry: { type: "<GeoJSON object type>" , coordinates: [ <coordinates> ] } } } }

Poniższa instancja użyje $geoIntersects do pobrania wszystkich danych loc, które przecinają się z wielokątem opisanym przez tablicę współrzędnych:

 db.places.find( { loc: { $geoIntersects: { $geometry: { type: "Polygon" , coordinates: [ [ [ 0, 0 ], [ 2, 6 ], [ 4, 1 ], [ 0, 0 ] ] ] } } } } )

$centrum

Operator $center wspomina o okręgu dla zapytania $geoWithin , które zwraca starsze pary współrzędnych, które znajdują się w granicach okręgu.

$center nie zwraca obiektów GeoJSON. Aby wykorzystać operator $center , musisz określić tablicę zawierającą:

  1. Promień okręgu mierzony w jednostkach układu współrzędnych.
  2. Współrzędne siatki punktu środkowego okręgu.
 { <location field> : { $geoWithin: { $center: [ [ <x> , <y> ] , <radius> ] } } }

Poniższy przykład zwróci wszystkie dokumenty, których współrzędne znajdują się w okręgu o środku [2,3] i promieniu 40:

 db.places.find( { loc: { $geoWithin: { $center: [ [2, 3], 40 ] } } } )

Operatorzy projekcji

Możesz użyć operatorów projekcji, aby wymienić pola zwrócone przez operację. Operatory projekcji MongoDB umożliwiają użycie funkcji find() z argumentami filtrowania danych. Pomaga to użytkownikom wyodrębnić z dokumentu tylko wymagane pola danych. Dzięki temu można projektować przejrzyste i zwięzłe dane bez wpływu na ogólną wydajność bazy danych.

$elemMatch (projekcja)

Operator $elemMatch jest odpowiedzialny za ograniczenie zawartości pola z wyników zapytania tak, aby zawierała tylko pierwszy element pasujący do $elemMatch .

Oto kilka rzeczy, o których musisz pamiętać przed użyciem $elemMatch :

  • Od MongoDB 4.4, niezależnie od kolejności pól w dokumencie, projekcja $elemMatch istniejącego pola zwraca pole po włączeniu innych istniejących pól.
  • Oba operatory $elemMatch i $ przedstawiają pierwszy pasujący element z tablicy na podstawie określonego warunku. Operator $ wyświetli pierwszy pasujący element tablicy z każdego dokumentu w kolekcji na podstawie pewnego warunku z instrukcji zapytania, podczas gdy operator projekcji $elemMatch przyjmuje jawny argument warunku. Pozwala to projektować w oparciu o warunek nieobecny w zapytaniu lub jeśli trzeba projektować w oparciu o różne pola w dokumentach osadzonych w tablicy.

Należy również pamiętać o następujących ograniczeniach przed użyciem operatora $elemMatch na swoich danych:

  • Nie możesz wspomnieć o wyrażeniu zapytania $ $text w operatorze $elemMatch .
  • db.collection.find() na widokach nie obsługują operatora projekcji $elemMatch .

Poniższy przykład na operatorze projekcji $elemMatch zakłada zbiór schools z następującymi dokumentami:

 { _id: 1, zipcode: "63108", students: [ { name: "mark", school: 102, age: 9 }, { name: "geoff", school: 101, age: 13 }, { name: "frank", school: 104, age: 12 } ] } { _id: 2, zipcode: "63110", students: [ { name: "harry", school: 103, age: 14 }, { name: "george", school: 103, age: 7 }, ] } { _id: 3, zipcode: "63108", students: [ { name: "harry", school: 103, age: 14 }, { name: "george", school: 103, age: 7 }, ] } { _id: 4, zipcode: "63110", students: [ { name: "jim", school: 103, age: 9 }, { name: "michael", school: 103, age: 12 }, ] }

W tym przypadku operacja find() wysyła zapytanie o wszystkie dokumenty, w których wartość pola zipcode wynosi 63110. Projekcja $elemMatch zwróci tylko pierwszy pasujący element tablicy students , w której pole school ma wartość 103:

 db.schools.find( { zipcode: "63110" }, { students: { $elemMatch: { school: 103 } } } ) This is what the result would look like: { "_id" : 2, "students" : [ { "name" : "harry", "school" : 103, "age" : 14 } ] } { "_id" : 4, "students" : [ { "name" : "jim", "school" : 103, "age" : 9 } ] }

$slice (rzut)

Operator projekcji $slice może służyć do określenia liczby elementów w tablicy, które mają zostać zwrócone w wyniku zapytania:

 db.collection.find( <query> , { <arrayField> : { $slice: <number> } } );

Można to również wyrazić w ten sposób:

 db.collection.find( <query> , { <arrayField> : { $slice: [ <number> , <number> ] } } );

Aby to zademonstrować, możesz stworzyć przykładową kolekcję tweetów z następującymi dokumentami:

 db.posts.insertMany([ { _id: 1, title: "Nuts are not blueberries.", comments: [ { comment: "0. true" }, { comment: "1. blueberries aren't nuts."} ] }, { _id: 2, title: "Coffee please.", comments: [ { comment: "0. Indubitably" }, { comment: "1. Cuppa tea please" }, { comment: "2. frappucino" }, { comment: "3. Mocha latte" }, { comment: "4. whatever" } ] } ])

Poniższa operacja użyje operatora projekcji $slice na tablicy tweets, aby zwrócić tablicę z jej pierwszymi dwoma elementami. Jeśli tablica zawiera mniej niż dwa elementy, zwracane są wszystkie elementy w tablicy:

 db.posts.find( {}, { comments: { $slice: 2 } } )

Ta operacja zwróciłaby następujące dokumenty:

 { "_id" : 1, "title" : "Nuts are not blueberries.", "comments" : [ { "comment" : "0. true" }, { "comment" : "1. blueberries aren't nuts." } ] } { "_id" : 2, "title" : "Coffee please.", "comments" : [ { "comment" : "0. Indubitably" }, { "comment" : "1. Cuppa tea please" } ] }

$ (projekcja)

Pozycyjny operator $ ogranicza zawartość tablicy do zwrócenia pierwszego elementu, który pasuje do warunku zapytania tej tablicy. Możesz użyć $ w dokumencie projekcji metody find() lub metody findOne() , gdy potrzebujesz tylko jednego określonego elementu tablicy w wybranych dokumentach.

Tak wygląda składnia operatora $ :

 db.collection.find( { <array>: <condition> ... }, { "<array>.$": 1 } ) db.collection.find( { <array.field>: <condition> ...}, { "<array>.$": 1 } )

W tym przykładzie kolekcja students składa się z następujących dokumentów:

 { "_id" : 1, "semester" : 2, "grades" : [ 75, 67, 93 ] } { "_id" : 2, "semester" : 2, "grades" : [ 60, 68, 72 ] } { "_id" : 3, "semester" : 2, "grades" : [ 95, 82, 67 ] } { "_id" : 4, "semester" : 3, "grades" : [ 89, 95, 70 ] } { "_id" : 5, "semester" : 3, "grades" : [ 68, 98, 82 ] } { "_id" : 6, "semester" : 3, "grades" : [ 65, 70, 76 ] }

W poniższym zapytaniu projekcja { "grades.$": 1 } zwraca tylko pierwszy element większy lub równy 89 dla pola grades :

 db.students.find( { semester: 2, grades: { $gte: 89 } }, { "grades.$": 1 } )

Ta operacja zwraca następujące dokumenty:

 {"_id": 3, "grades": [95] }

Operatory oceny

Możesz wykorzystać operatory oceny MongoDB do oceny ogólnej struktury danych lub poszczególnych pól w dokumencie.

Przyjrzyjmy się niektórym typowym operatorom oceny MongoDB.

$mod

Możesz użyć tego operatora, aby dopasować dokumenty, w których wartość określonego pola jest równa reszcie po podzieleniu przez określoną wartość:

 { field: { $mod: [ divisor, remainder ] } }

Załóżmy, że masz w swoim salonie stół z samochodami różnych marek. Poniższe zapytanie wyświetli wszystkie marki samochodów, których numery magazynowe są wielokrotnością 250.

 db.cars.find ( { qty: { $mod: [ 250,0 ] } } )

$jsonSchema

$jsonSchema pozwala dopasować dokumenty, które pasują do określonego schematu JSON. Implementacja schematu JSON w MongoDB obejmuje dodanie słowa kluczowego bsonType , które umożliwia korzystanie ze wszystkich typów BSON w ramach operatora $jsonSchema .

bsonType może akceptować te same aliasy ciągów znaków, których użyłbyś dla operatora type . Tak wyglądałaby składnia $jsonSchema :

 { $jsonSchema: <JSON Schema object> }

W tym przypadku obiekt schematu JSON jest sformatowany na podstawie wersji roboczej standardu schematu JSON 4:

 { <keyword1>: <value1>, ... }

Oto przykład pokazujący, jak działa $jsonSchema :

 { $jsonSchema: { required: [ "name", "major", "gpa", "address" ], properties: { name: { bsonType: "string", description: "must be a string and is required" }, address: { bsonType: "object", required: [ "zipcode" ], properties: { "street": { bsonType: "string" }, "zipcode": { bsonType: "string" } } } } } }

Możesz również użyć $jsonSchema w walidatorze dokumentów, aby wymusić określony schemat podczas operacji aktualizacji i wstawiania:

 db.createCollection(<collection> , { validator: { $jsonSchema: <schema> } } ) db.runCommand( { collMod: <collection>, validator:{ $jsonSchema: <schema> } } )

Pamiętaj, że operator $jsonSchema nie obsługuje kilku rzeczy:

  1. Typ liczby całkowitej. Musisz wykorzystać typ BSON long lub int za pomocą słowa kluczowego bsonType.
  2. Nieznane słowa kluczowe.
  3. Łączenie właściwości i hipermediów schematu JSON wraz z wykorzystaniem odwołań JSON i wskaźników JSON.

$tekst

Operator $text szukałby tekstu w treści określonego pola, zindeksowanego indeksem tekstowym:

 { $text: { $search: <string>, $language: <string>, $caseSensitive: <boolean>, $diacriticSensitive: <boolean> } }

W tym przypadku poniższy fragment kodu przeszuka tabelę, aby odfiltrować wszystkie samochody, które mają w sobie tekst „Porsche”:

 db.cars.find( { $text: { $search: "Porsche" } } )

$regex

Operator $regex oferuje możliwość wyrażenia regularnego do dopasowywania wzorców w zapytaniach. MongoDB wykorzystuje wyrażenia regularne zgodne z Perlem:

 {<field> : /pattern/ <options>}

Poniższy przykład pomoże odfiltrować wszystkie samochody, w których występuje ciąg „78900 USD”:

 db.cars.find( { price: { $regex: /$78900/ } } )

$wyraz

Operator $expr umożliwia wykorzystanie wyrażeń agregujących w języku zapytań:

 { $expr: { <expression> } }

Możesz również użyć $expr do tworzenia wyrażeń zapytań, które porównują pola z tego samego dokumentu na etapie $match . If the $match stage happens to be the part of a $lookup stage, $expr can compare fields with the help of let variables.

$where

You can leverage the $where operator to either pass a string containing a full JavaScript function or a JavaScript expression to the query system. The $where operator provides greater flexibility but needs the database to process the JavaScript function or expression for every document in the collection. You can reference this document in the JavaScript function or expression by using either obj or this .

Here's an example of the syntax:

 { $where: <string|JavaScript Code> }

There are a few key considerations to keep in mind before we dive into an example while using the $where operator:

  • You should only use the $where query operator to top-level documents. The $where query operator won't function in a nested document, like in a $elemMatch query.
  • Generally, you should use $where only when you cannot express your query via another operator. If you have to use $where , make sure you include at least one other standard query operator to filter the result set. Using $where independently requires a collection scan for proper execution.

Here's an example to illustrate this:

 db.cars.find( { $where: function() { return (hex_md5(this.name)== "9a43e617b50cd379dca1bc6e2a8") } } );

Bitwise Operators

Bitwise operators return data based on bit position conditions. Simply put, they are used to match numeric or binary values in which any bit from a set of bit positions has a value of 1 or 0.

$bitsAllSet

This operator will match all the documents where all of the bit positions provided by the query are set (ie 1) in the field:

{ <field> : { $bitsAllSet: <numeric bitmask> } }
 { <field> : { $bitsAllSet: < BinData bitmask> } }
 { <field> : { $bitsAllSet: [ <position1> , <position2> , ... ] } }

Wartość pola powinna być instancją BinData lub wartością liczbową, aby $bitsAllSet była zgodna z bieżącym dokumentem.

W następującym przypadku wykorzystujemy kolekcję z następującymi dokumentami:

 db.collection.save({ _id: 1, a: 54, binaryValueofA: "00110110" }) db.collection.save({ _id: 2, a: 20, binaryValueofA: "00010100" }) db.collection.save({ _id: 3, a: 20.0, binaryValueofA: "00010100" }) db.collection.save({ _id: 4, a: BinData(0, "Zg=="), binaryValueofA: "01100110" })

Zapytanie wymienione poniżej użyje operatora $bitsAllSet do sprawdzenia, czy pole a ma ustawione bity na pozycji 1 i pozycji 5, gdzie najmniej znaczący bit będzie na pozycji 0:

 db.collection.find( { a: { $bitsAllSet: [ 1, 5 ] } }

To zapytanie pasowałoby do następujących dokumentów:

 { "_id" : 1, "a" : 54, "binaryValueofA" : "00110110" } { "_id" : 4, "a" : BinData(0,"Zg=="), "binaryValueofA" : "01100110" }

$bitsAllClear

Operator $bitsAllClear dopasuje dokumenty, w których wszystkie pozycje bitów podane przez zapytanie są czyste lub 0 :

 { <field> : { $bitsAllClear: <numeric bitmask> } }
 { <field> : { $bitsAllClear: < BinData bitmask> } }
 { <field> : { $bitsAllClear: [ <position1> , <position2> , ... ] } }

Użyjemy przykładu użytego dla $bitsAllSet tutaj, aby zademonstrować użycie $bitsAllClear . Następujące zapytanie użyje tego operatora do sprawdzenia, czy pole a ma wolne bity na pozycjach 1 i 5:

 db.collection.find( { a: { $bitsAllClear: [ 1, 5 ] } } )

To zapytanie pasowałoby do następujących dokumentów:

 { "_id" : 2, "a" : 20, "binaryValueofA" : "00010100" } { "_id" : 3, "a" : 20, "binaryValueofA" : "00010100" }

Metaoperatorzy

Istnieją różne modyfikatory zapytań, które pozwalają modyfikować zachowanie lub dane wyjściowe zapytania w MongoDB. Interfejsy sterownika mogą udostępniać metody kursora, które otaczają je do użytku.

$podpowiedź

MongoDB wycofało $hint od wersji 3.2. Jednak operator ten może być nadal dostępny dla sterowników MongoDB, takich jak Go, Java, Scala, Ruby, Swift itp. Może on zmusić optymalizator zapytań do wykorzystania określonego indeksu do wykonania zapytania, o którym można następnie wspomnieć w dokumencie lub przez nazwa indeksu.

Możesz również użyć operatora $hint do testowania strategii indeksowania i wydajności zapytań. Na przykład wykonaj następującą operację:

 db.users.find().hint( { age: 1 } )

Ta operacja zwróci wszystkie dokumenty w kolekcji o nazwie users , wykorzystując indeks w polu age .

Możesz również wspomnieć o podpowiedzi, używając jednej z następujących form:

 db.users.find()._addSpecial( "$hint", { age : 1 } ) db.users.find( { $query: {}, $hint: { age : 1 } } )

Jeśli istnieje filtr indeksu dla kształtu zapytania, MongoDB po prostu zignoruje $hint .

$komentarz

Operator $comment umożliwia dołączenie komentarza do zapytania w dowolnym kontekście, w którym może pojawić się $query . Ponieważ komentarze są propagowane do dziennika profilu, dodanie komentarza może ułatwić interpretację i śledzenie profilu.

Możesz wykorzystać $comment na jeden z trzech sposobów:

 db.collection.find( { <query> } )._addSpecial( "$comment", <comment> ) db.collection.find( { <query> } ).comment( <comment> ) db.collection.find( { $query: { <query> }, $comment: <comment> } )

Jeśli chcesz dołączyć komentarze do wyrażeń zapytań w innych kontekstach, na przykład za pomocą db.collection.update() , użyj operatora zapytania $comment zamiast metaoperatora.

$maks.

Możesz wspomnieć o wartości $max , aby określić górną granicę wyłączności dla konkretnego indeksu, aby ograniczyć wyniki funkcji find() . Ten operator określi górną granicę dla wszystkich kluczy określonej kolejności w indeksie.

Mongosh udostępnia następującą metodę opakowującą max() :

 db.collection.find( { <query> } ).max( { field1: <max value> , ... fieldN: <max valueN> } )

Możesz również wspomnieć o $max w dwóch następujących formach:

 db.collection.find( { <query> } )._addSpecial( "$max", { field1: <max value1> , ... fieldN: <max valueN> } ) db.collection.find( { $query: { <query> }, $max: { field1: <max value1> , ... fieldN: <max valueN> } } )

Na przykład, jeśli chcesz określić górną granicę wyłączności, pamiętaj o następujących operacjach na kolekcji o nazwie kolekcja, która zawiera indeks { age: 1 } :

 db.collection.find( { <query> } ).max( { age: 100 } ).hint( { age: 1 } )

Ta operacja ograniczy zapytanie do tych dokumentów, w których wiek pola jest mniejszy niż 100 i wymusza plan zapytania, który będzie skanował indeks { age: 1 } od minKey do 100.

$wyjaśnij

Ten operator poda informacje o planie zapytania. Zwraca dokument opisujący indeksy i procesy użyte do zwrócenia zapytania. Może to być przydatne podczas próby optymalizacji zapytania.

Możesz wymienić operator $explain w jednej z następujących form:

 db.collection.find()._addSpecial( "$explain", 1 ) db.collection.find( { $query: {}, $explain: 1 } )

Najlepsze praktyki dla operatorów MongoDB

W tej sekcji przyjrzymy się niektórym najlepszym praktykom podczas korzystania z tych operatorów MongoDB.

Osadzanie i odwoływanie się

Osadzanie to naturalne rozszerzenie modelowania danych. Pozwala uniknąć łączenia aplikacji, co może zmniejszyć liczbę aktualizacji i zapytań.

W pojedynczym dokumencie można osadzić dane w relacji 1:1. To powiedziawszy, dane z relacją wiele:1, w której „wiele” obiektów pojawia się z dokumentami nadrzędnymi, również mogą być dobrymi kandydatami.

Przechowywanie tego typu danych w tym samym dokumencie brzmi jak rozsądny wybór. Jednak osadzanie zapewnia lepszą wydajność operacji odczytu z tego rodzaju lokalizacją danych.

Osadzone modele danych mogą również pomóc deweloperom w aktualizowaniu skojarzonych danych w jednej operacji zapisu. Działa to, ponieważ zapisy pojedynczego dokumentu są transakcyjne.

Należy rozważyć użycie odwołań w następujących scenariuszach:

  • Gdy aktualizujesz segment dokumentu i staje się on coraz dłuższy, podczas gdy reszta dokumentu jest statyczna.
  • Gdy uzyskuje się dostęp do dokumentu, ale zawiera dane, które są rzadko używane. Osadzanie zwiększyłoby tylko wymagania dotyczące pamięci, więc odwoływanie się ma więcej sensu.
  • Gdy rozmiar dokumentu przekroczy limit dokumentów MongoDB 16 MB. Może się to zdarzyć podczas modelowania relacji wiele:1 (na przykład pracownicy:dział ).

Zbadaj profilowanie i wzorce zapytań

Dla większości programistów pierwszym krokiem w optymalizacji wydajności jest zrozumienie rzeczywistych i oczekiwanych wzorców zapytań. Gdy znasz już wystarczająco dobrze wzorce zapytań swojej aplikacji, możesz stworzyć swój model danych i wybrać odpowiednie indeksy.

Deweloperzy MongoDB mają dostęp do różnych potężnych narzędzi, które pozwalają im poprawić wydajność. Nie oznacza to jednak, że profile i wzorce zapytań można zignorować.

Na przykład jednym prostym sposobem na zwiększenie wydajności jest analiza wzorców zapytań i zrozumienie, gdzie można osadzić dane. Inne sposoby na zwiększenie wydajności MongoDB po zidentyfikowaniu głównych wzorców zapytań obejmują:

  • Upewnij się, że masz indeksy na polach, których dotyczy zapytanie.
  • Przechowywanie wyników częstych podzapytań dotyczących dokumentów w celu zmniejszenia obciążenia odczytu.
  • Spojrzenie na swoje logi, aby przyjrzeć się powolnym zapytaniom, a następnie sprawdzenie indeksów.

Przegląd indeksowania i modelowania danych

Tworząc model danych, będziesz decydować, jak modelować relacje między danymi. Na przykład wybór, kiedy osadzić dokument, zamiast tworzyć odwołanie w osobnych dokumentach w różnych kolekcjach, jest przykładem rozważań dotyczących konkretnej aplikacji.

Główną zaletą dokumentów JSON jest to, że umożliwiają programistom modelowanie danych na podstawie wymagań aplikacji. Zagnieżdżanie dokumentów podrzędnych i tablic pomaga modelować złożone relacje między danymi dzięki wykorzystaniu prostych dokumentów tekstowych.

MongoDB można również użyć do modelowania następujących elementów:

  • Dane geoprzestrzenne
  • Konstrukcje tabelaryczne, płaskie i kolumnowe
  • Proste pary klucz-wartość
  • Dane szeregów czasowych
  • Krawędzie i węzły połączonych grafowych struktur danych i tym podobne

Monitoruj fragmentowanie i replikację

Replikacja może mieć kluczowe znaczenie dla poprawy wydajności, ponieważ zwiększa dostępność danych dzięki skalowaniu poziomemu. Replikacja może prowadzić do lepszej wydajności i większego bezpieczeństwa dzięki nadmiarowości.

Monitorowanie wydajności może być kłopotliwe, wymagające dodatkowych zasobów i czasu, aby zapewnić płynne działanie. Możesz wykorzystać dostępne na rynku narzędzia do monitorowania wydajności, które zaspokoją Twoje specyficzne potrzeby.

Na przykład Kinsta APM może pobierać informacje ze znacznikiem czasu dotyczące zapytań do bazy danych MySQL witryny WordPress, procesów PHP, zewnętrznych wywołań HTTP i wielu innych. Możesz także użyć tego bezpłatnego narzędzia do debugowania:

  • Długie wywołania API
  • Żądania długich zewnętrznych adresów URL
  • Powolne zapytania do bazy danych, aby wymienić tylko kilka.

W MongoDB replikację można osiągnąć za pomocą zestawów replik, które umożliwiają programistom kopiowanie danych z głównego węzła lub serwera na wiele dodatkowych. Dzięki temu replikacja może uruchamiać niektóre zapytania na serwerach pomocniczych, a nie na podstawowych, unikając rywalizacji i prowadząc do lepszego równoważenia obciążenia.

Klastry podzielone na fragmenty w MongoDB to kolejny sposób na potencjalne zwiększenie wydajności. Podobnie jak w przypadku replikacji, fragmentów można użyć do dystrybucji dużych zestawów danych na wielu serwerach.

Wykorzystując klucz fragmentu, programiści mogą kopiować fragmenty lub fragmenty danych na wiele serwerów. Te serwery mogą współpracować, aby wykorzystać wszystkie dane.

Sharding ma wiele zalet, w tym skalowanie poziome dla zapisów/odczytów, wyższą dostępność i zwiększoną pojemność pamięci.

Określ użycie pamięci

MongoDB działa najlepiej, gdy zestaw roboczy aplikacji (tj. często używane dane i indeksy) mieści się w pamięci bez problemów. Podczas gdy inne czynniki mają kluczowe znaczenie dla wydajności, rozmiar pamięci RAM jest najważniejszy, na przykład rozmiar.

Gdy zestaw roboczy aplikacji mieści się w pamięci RAM, aktywność odczytu z dysku musi być niska. Ale jeśli twój zestaw roboczy przekracza pamięć RAM serwera instancji lub rozmiar, aktywność odczytu zacznie rosnąć.

Jeśli zauważysz, że tak się dzieje, możesz rozwiązać problem, przechodząc do większej instancji, która ma więcej pamięci.

Umieść pola wielowartościowe na końcu

Jeśli indeksujesz kilka pól, a jedno z pól, które chcesz zbadać, używa jednego z tych „wielowartościowych” operatorów, powinieneś umieścić je na końcu indeksu. Indeks należy uporządkować w taki sposób, aby pola dla dokładnych wartości, których dotyczy zapytanie, znajdowały się na pierwszym miejscu, a operatory „wielowartościowe” pojawiały się na końcu indeksu.

Wyjątkiem od tego byłoby sortowanie według pól. Umieść je między polami „wielowartościowymi” i dokładnymi, aby zmniejszyć ilość potrzebnego sortowania w pamięci.

Streszczenie

W przypadku MongoDB szybkość to nazwa gry. Aby szybko zwracać zapytania, MongoDB wykorzystuje operatorów do wykonywania zadań matematycznych lub logicznych. Mówiąc najprościej, zrozumienie operatorów MongoDB jest kluczem do opanowania MongoDB.

W tym artykule podkreślono niektóre kluczowe operatory MongoDB, których można używać na danych, takie jak operatory porównania, operatory logiczne, operatory meta i operatory projekcji, aby wymienić tylko kilka. Pomaga również zrozumieć, w jaki sposób można używać operatorów MongoDB i najlepsze praktyki, które pozwolą Ci wydobyć z nich to, co najlepsze.

Spośród wszystkich operatorów, którego(ych) używasz najczęściej i dlaczego? Podziel się w komentarzach poniżej — chętnie poznamy Twoje przemyślenia!