Udostępnij przez


Zarządzanie indeksowaniem w usłudze Azure DocumentDB

Indeksy to struktury, które zwiększają szybkość pobierania danych, zapewniając szybki dostęp do pól w kolekcji. Działają one przez utworzenie uporządkowanego zestawu wskaźników na dane, często na podstawie kluczowych pól. Usługa Azure DocumentDB korzysta z indeksów w wielu kontekstach, w tym wypychania zapytań, unikatowych ograniczeń i fragmentowania.

Ważne

Pole "_id" jest jedynym polem indeksowanym domyślnie i maksymalnym rozmiarem pola może być 2 KB. Zaleca się dodanie dodatkowych indeksów na podstawie filtrów zapytań i predykatów w celu zoptymalizowania wydajności.

Typy indeksów

Dla uproszczenia rozważmy przykład aplikacji blogu z następującą konfiguracją:

  • Nazwa bazy danych: cosmicworks
  • Nazwa kolekcji: products

Ta przykładowa aplikacja przechowuje artykuły jako dokumenty z następującą strukturą. Wszystkie cytowane dalej przykłady wykorzystują strukturę tej kolekcji.

{
  "_id": ObjectId("617a34e7a867530bff1b2346"),
  "title": "Azure DocumentDB - A Game Changer",
  "content": "Azure DocumentDB is a globally distributed, multi-model database service.",
  "author": {lastName: "Doe", firstName: "John"},
  "category": "Technology",
  "launchDate": ISODate("2024-06-24T10:08:20.000Z"),
  "published": true
}

Indeksy z pojedynczym polem

Pojedyncze indeksy pól przechowują informacje z jednego pola w kolekcji. Kolejność sortowania indeksu pojedynczego pola nie ma znaczenia. _id pole pozostaje domyślnie indeksowane.

Usługa Azure DocumentDB obsługuje tworzenie indeksu w następujący sposób

  • Pola dokumentów najwyższego poziomu.
  • Dokument osadzony.
  • Pola w dokumencie osadzonym.

Polecenie poniżej tworzy indeks na pojedynczym polu author, a kolejne polecenie tworzy go na osadzonym polu firstName.

use cosmicworks

db.products.createIndex({"author": 1})

// indexing embedded property
db.products.createIndex({"author.firstName": -1})

Jedno zapytanie może używać wielu pojedynczych indeksów pól, jeśli są dostępne.

Uwaga / Notatka

Usługa Azure DocumentDB umożliwia tworzenie maksymalnie 64 indeksów w kolekcji. W zależności od poziomu, na żądanie możemy zaplanować rozszerzenie do 300 indeksów.

Indeksy złożone

Indeksy złożone zwiększają wydajność bazy danych, umożliwiając wydajne wykonywanie zapytań i sortowanie na podstawie wielu pól w dokumentach. Ta optymalizacja zmniejsza konieczność skanowania całych kolekcji, przyspieszania pobierania danych i organizacji.

Następujące polecenie tworzy indeks złożony w polach author i launchDate w odwrotnej kolejności sortowania.

use cosmicworks

db.products.createIndex({"author":1, "launchDate":-1})

Order pola mają wpływ na selektywność lub wykorzystanie indeksu. Kwerenda find nie będzie korzystać z utworzonego indeksu.

use cosmicworks

db.products.find({"launchDate": {$gt: ISODate("2024-06-01T00:00:00.000Z")}})

Ograniczenia

  • Maksymalnie 32 pola\ścieżki w indeksie złożonym.

Indeksy częściowe

Indeksy, które mają skojarzony filtr zapytania, który opisuje, kiedy wygenerować termin w indeksie.

use cosmicworks

db.products.createIndex (
   { "author": 1, "launchDate": 1 },
   { partialFilterExpression: { "launchDate": { $gt: ISODate("2024-06-24T10:08:20.000Z") } } }
)

Ograniczenia

  • Indeksy częściowe nie obsługują ORDER BY ani UNIQUE, chyba że filtr spełnia określone warunki.

Indeksy tekstowe

Indeksy tekstowe to specjalne struktury danych, które optymalizują zapytania oparte na tekście, co sprawia, że są szybsze i bardziej wydajne.

Użyj metody createIndex z opcją text, aby tworzyć indeks tekstowy w polu title.

use cosmicworks;

db.products.createIndex({ title: "text" })

Uwaga / Notatka

Chociaż można zdefiniować tylko jeden indeks tekstowy dla kolekcji, usługa Azure DocumentDB umożliwia tworzenie indeksów tekstowych w kombinacji wielu pól w celu umożliwienia wykonywania wyszukiwań tekstowych w różnych polach w dokumentach.

Konfigurowanie opcji indeksu tekstowego

Indeksy tekstowe w usłudze Azure DocumentDB mają kilka opcji dostosowywania ich zachowania. Można na przykład określić język analizy tekstu, ustawić wagi, aby określić priorytety niektórych pól i skonfigurować wyszukiwania bez uwzględniania wielkości liter. Oto przykład tworzenia indeksu tekstowego z opcjami:

  • Utwórz indeks do obsługi wyszukiwania w polach title i content z obsługą języka angielskiego. Ponadto przypisz większe wagi do title pola, aby określić priorytety w wynikach wyszukiwania.

    use cosmicworks
    
    db.products.createIndex(
        { title: "text", content: "text" },
        { default_language: "english", weights: { title: 10, content: 5 }, caseSensitive: false }
    )
    

Uwaga / Notatka

Gdy klient wykonuje zapytanie wyszukiwania tekstowego z terminem "DocumentDB", wynik dla każdego dokumentu w kolekcji zostanie obliczony na podstawie obecności i częstotliwości terminu zarówno w polach "title" i "content", o większej ważności dla pola "title" ze względu na większą wagę.

Wyszukiwanie tekstu przy użyciu indeksu tekstowego

Po utworzeniu indeksu tekstu można wykonywać wyszukiwania tekstowe przy użyciu operatora "text" w zapytaniach. Operator tekstu przyjmuje ciąg wyszukiwania i dopasuje go do indeksu tekstu w celu znalezienia odpowiednich dokumentów.

  • Wykonaj wyszukiwanie tekstu dla frazy DocumentDB.

    use cosmicworks
    
    db.products.find(
      { $text: { $search: "DocumentDB" } }
    )
    
  • Opcjonalnie użyj operatora projekcji $meta w zapytaniu wraz z polem textScore, aby zobaczyć wagę

    use cosmicworks
    
    db.products.find(
    { $text: { $search: "DocumentDB" } },
    { score: { $meta: "textScore" } }
    )
    

Ograniczenia

  • W kolekcji można zdefiniować tylko jeden indeks tekstowy.
  • Operacje sortowania nie mogą używać kolejności indeksu tekstowego w bazie danych MongoDB.
  • Wskazówka() nie jest obsługiwana w połączeniu z zapytaniem używającym wyrażenia $text.
  • Indeksy tekstowe mogą być stosunkowo duże, zużywając znaczną ilość miejsca do magazynowania w porównaniu z innymi typami indeksów.

Indeksy symboli wieloznacznych

Indeks w pojedynczym polu obejmuje wszystkie ścieżki poniżej field, z pominięciem innych pól znajdujących się na tym samym poziomie. Na przykład w poniższym przykładowym dokumencie

{
 "children":
    {
     "familyName": "Merriam",
     "pets": { "details": {“name”: "Goofy", ”age”: 3} }
   } 
}

Tworzenie indeksu na { "pets.$**": 1 }, tworzy indeks na właściwościach informacji szczegółowych i subdokumentu, ale nie tworzy indeksu na "familyName".

Ograniczenia

  • Indeksy typu wildcard nie mogą obsługiwać unikalnych indeksów.
  • Indeksy wieloznaczne nie obsługują przenoszenia ORDER BY, chyba że filtr zawiera tylko ścieżki obecne w indeksie wieloznaczności (ponieważ nie indeksują niezdefiniowanych elementów)
  • Złożony indeks wieloznaczny może zawierać tylko jeden termin wieloznaczny one i one lub więcej terminów indeksu. { "pets.$**": 1, “familyName”: 1 }

Indeksy geoprzestrzenne

Indeksy geoprzestrzenne obsługują zapytania dotyczące danych przechowywanych jako obiekty GeoJSON lub starsze pary współrzędnych. Za pomocą indeksów geoprzestrzennych można zwiększyć wydajność zapytań dotyczących danych geoprzestrzennych lub uruchamiać pewne zapytania geoprzestrzenne.

Usługa Azure DocumentDB udostępnia dwa typy indeksów geoprzestrzennych:

  • Indeksy 2dsphere, które obsługują zapytania interpretujące geometrię na sferze.
  • Indeksy 2d, które obsługują zapytania interpretujące geometrię na płaskiej powierzchni.

Indeksy 2D

Indeksy 2d są obsługiwane tylko w przypadku tradycyjnego stylu par koordynat przechowywania danych geograficznych.

Użyj metody createIndex z opcją 2d do tworzenia indeksu geoprzestrzennego w polu location.

db.places.createIndex({ "location": "2d"});

Ograniczenia

  • Tylko one pole lokalizacji może być częścią indeksu2d, a tylko one inne pole nieprzestrzenne może być częścią indeksu compound 2ddb.places.createIndex({ "location": "2d", "non-geospatial-field": 1 / -1 })

Indeksy 2dsphere

2dsphere Indeksy obsługują zapytania geoprzestrzenne na sferze podobnej do ziemi. Może obsługiwać zarówno obiekty GeoJSON, jak i starsze pary współrzędnych. 2dSphere indeksy współpracują z formatem przechowywania danych GeoJSON. Jeśli napotkane zostaną starsze punkty, zostaną one przekonwertowane na punkty GeoJSON.

Użyj metody createIndex z opcją 2dsphere do tworzenia indeksu geoprzestrzennego w polu location.

db.places.createIndex({ "location": "2dsphere"});

2dsphere indeksy umożliwiają tworzenie indeksów w wielu polach danych geoprzestrzennych i nieprzestrzennych. db.places.createIndex({ "location": "2d", "non-geospatial-field": 1 / -1, ... "more non-geospatial-field": 1 / -1 })

Ograniczenia

  • Indeks złożony używający zwykłego indeksu i indeksu geoprzestrzennego nie jest obsługiwany. Utworzenie jednego z indeksów geoprzestrzennych spowodowałoby błędy.

    // Compound Regular & 2dsphere indexes are not supported yet
    db.collection.createIndex({a: 1, b: "2dsphere"})
    
    // Compound 2d indexes are not supported yet
    db.collection.createIndex({a: "2d", b: 1})
    
  • Wielokąty z otworami nie działają. Wstawianie wielokąta z otworem nie jest ograniczone, choć $geoWithin zapytanie kończy się niepowodzeniem w scenariuszach:

    1. Jeśli samo zapytanie ma wielokąt z otworami

      coll.find(
        {
            "b": {
                "$geoWithin": {
                    "$geometry": {
                        "coordinates": [
                            [
                                [ 0, 0], [0, 10], [10, 10],[10,0],[0, 0]
                            ],
                            [
                                [5, 5], [8, 5], [ 8, 8], [ 5, 8], [ 5, 5]
                            ]
                        ],
                        "type": "Polygon"
                    }
                }
            }
        })
      
      // MongoServerError: $geoWithin currently doesn't support polygons with holes
      
    2. Jeśli istnieje jakikolwiek niefiltrowany dokument, który ma wielokąt z otworami.

      [mongos] test> coll.find()
        [
          {
            _id: ObjectId("667bf7560b4f1a5a5d71effa"),
            b: {
              type: 'Polygon',
              coordinates: [
                [ [ 0, 0 ], [ 0, 10 ], [ 10, 10 ], [ 10, 0 ], [ 0, 0 ] ],
                [ [ 5, 5 ], [ 8, 5 ], [ 8, 8 ], [ 5, 8 ], [ 5, 5 ] ]
              ]
            }
          }
        ]
      // MongoServerError: $geoWithin currently doesn't support polygons with holes
      
    3. key pole jest obowiązkowe podczas korzystania z geoNear.

       [mongos] test> coll.aggregate([{ $geoNear: { $near: { "type": "Point", coordinates: [0, 0] } } }])
      
       // MongoServerError: $geoNear requires a 'key' option as a String
      

Dalsze kroki