Udostępnij za pośrednictwem


Obliczone właściwości w usłudze Azure Cosmos DB for NoSQL

DOTYCZY: NoSQL

Obliczone właściwości w usłudze Azure Cosmos DB mają wartości pochodzące z istniejących właściwości elementu, ale właściwości nie są utrwalane w samych elementach. Obliczone właściwości są ograniczone do pojedynczego elementu i mogą być przywoływane w zapytaniach tak, jakby były utrwalane właściwości. Obliczone właściwości ułatwiają wielokrotne pisanie złożonej logiki zapytań i odwoływanie się do niej wiele razy. Można dodać pojedynczy indeks dla tych właściwości lub użyć ich jako części indeksu złożonego w celu zwiększenia wydajności.

Uwaga

Czy masz jakieś opinie na temat obliczonych właściwości? Chcemy to usłyszeć! Możesz podzielić się opiniami bezpośrednio z zespołem inżynierów usługi Azure Cosmos DB: cosmoscomputedprops@microsoft.com.

Co to jest obliczona właściwość?

Obliczone właściwości muszą znajdować się na najwyższym poziomie elementu i nie mogą mieć ścieżki zagnieżdżonej. Każda obliczona definicja właściwości ma dwa składniki: nazwę i zapytanie. Nazwa jest nazwą obliczonej właściwości, a zapytanie definiuje logikę obliczania wartości właściwości dla każdego elementu. Obliczone właściwości są ograniczone do pojedynczego elementu i dlatego nie mogą używać wartości z wielu elementów ani polegać na innych obliczonych właściwościach. Każdy kontener może mieć maksymalnie 20 obliczonych właściwości.

Przykładowa definicja właściwości obliczonej:

{
  "computedProperties": [
    {
      "name": "cp_lowerName",
      "query": "SELECT VALUE LOWER(c.name) FROM c"
    }
  ]
}

Ograniczenia nazw

Zdecydowanie zalecamy nadenie właściwościom obliczonym nazw, aby nie istniała kolizja z utrwalonej nazwy właściwości. Aby uniknąć nakładania się nazw właściwości, można dodać prefiks lub sufiks do wszystkich obliczonych nazw właściwości. W tym artykule użyto prefiksu cp_ we wszystkich definicjach nazw.

Ważne

Zdefiniowanie obliczonej właściwości przy użyciu tej samej nazwy co utrwalonej właściwości nie powoduje błędu, ale może prowadzić do nieoczekiwanego zachowania. Niezależnie od tego, czy właściwość obliczana jest indeksowana, wartości z właściwości trwałych, które współużytkują nazwę z właściwością obliczaną, nie będą uwzględniane w indeksie. W zapytaniach zawsze będzie używana właściwość obliczana zamiast właściwości trwałej z wyjątkiem właściwości trwałej zwracanej zamiast właściwości obliczanej, jeśli w klauzuli SELECT jest projekcja symbolu wieloznacznego. Projekcja wieloznaczny nie zawiera automatycznie obliczonych właściwości.

Ograniczenia dotyczące obliczonych nazw właściwości to:

  • Wszystkie obliczone właściwości muszą mieć unikatowe nazwy.
  • Wartość name właściwości reprezentuje nazwę właściwości najwyższego poziomu, która może służyć do odwołowania się do obliczonej właściwości.
  • Zastrzeżone nazwy właściwości systemowych, takie jak id, _ridi _ts nie mogą być używane jako nazwy właściwości obliczonych.
  • Nazwa obliczonej właściwości nie może być zgodna ze ścieżką właściwości, która jest już indeksowana. To ograniczenie dotyczy wszystkich określonych ścieżek indeksowania, w tym:
    • Dołączone ścieżki
    • Wykluczone ścieżki
    • Indeksy przestrzenne
    • Indeksy złożone

Ograniczenia zapytań

Zapytania w definicji właściwości obliczeniowej muszą być prawidłowe składniowo i semantycznie. W przeciwnym razie operacja tworzenia lub aktualizacji kończy się niepowodzeniem. Zapytania powinny mieć wartość deterministyczną dla wszystkich elementów w kontenerze. Zapytania mogą oceniać wartości niezdefiniowane lub null dla niektórych elementów, a obliczone właściwości z niezdefiniowanym lub null zachowują się tak samo jak utrwalone właściwości z niezdefiniowanym lub zerowym wartościami w przypadku użycia w zapytaniach.

Ograniczenia dotyczące definicji zapytań właściwości obliczanych to:

  • Zapytania muszą określać klauzulę FROM reprezentującą odwołanie do elementu głównego. Przykłady obsługiwanych klauzul FROM to: FROM c, FROM root ci FROM MyContainer c.
  • Zapytania muszą używać klauzuli VALUE w projekcji.
  • Kwerendy nie mogą zawierać sprzężenia.
  • Zapytania nie mogą używać niedeterministycznych wyrażeń skalarnych. Przykłady niedeterministycznych wyrażeń skalarnych to: GetCurrentDateTime, GetCurrentTimeStamp, GetCurrentTicks i RAND.
  • Kwerendy nie mogą używać żadnych z następujących klauzul: WHERE, GROUP BY, ORDER BY, TOP, DISTINCT, OFFSET LIMIT, EXISTS, ALL, LAST, FIRST i NONE.
  • Zapytania nie mogą zawierać podzapytania skalarnego.
  • Funkcje agregujące, funkcje przestrzenne, funkcje nieokreślone i funkcje zdefiniowane przez użytkownika (UDF) nie są obsługiwane.

Tworzenie obliczonych właściwości

Po utworzeniu obliczonych właściwości można wykonywać zapytania odwołujące się do właściwości przy użyciu dowolnej metody, w tym wszystkich zestawów SDK i usługi Azure Data Explorer w witrynie Azure Portal.

Obsługiwana wersja Uwagi
Zestaw .NET SDK w wersji 3 >= 3.34.0-preview Obliczone właściwości są obecnie dostępne tylko w wersjach pakietu w wersji zapoznawczej.
Zestaw Java SDK w wersji 4 >= 4.46.0 Obliczone właściwości są obecnie w wersji zapoznawczej.
Zestaw SDK dla języka Python >= v4.5.2b5 Obliczone właściwości są obecnie w wersji zapoznawczej.

Tworzenie obliczonych właściwości przy użyciu zestawu SDK

Możesz utworzyć nowy kontener z zdefiniowanymi właściwościami obliczeniowymi lub dodać obliczone właściwości do istniejącego kontenera.

Oto przykład tworzenia obliczonych właściwości w nowym kontenerze:

ContainerProperties containerProperties = new ContainerProperties("myContainer", "/pk")
{
    ComputedProperties = new Collection<ComputedProperty>
    {
        new ComputedProperty
        {
            Name = "cp_lowerName",
            Query = "SELECT VALUE LOWER(c.name) FROM c"
        }
    }
};

Container container = await client.GetDatabase("myDatabase").CreateContainerAsync(containerProperties);

Oto przykład aktualizowania obliczonych właściwości istniejącego kontenera:

var container = client.GetDatabase("myDatabase").GetContainer("myContainer");

// Read the current container properties
var containerProperties = await container.ReadContainerAsync();
// Make the necessary updates to the container properties
containerProperties.Resource.ComputedProperties = new Collection<ComputedProperty>
    {
        new ComputedProperty
        {
            Name = "cp_lowerName",
            Query = "SELECT VALUE LOWER(c.name) FROM c"
        },
        new ComputedProperty
        {
            Name = "cp_upperName",
            Query = "SELECT VALUE UPPER(c.name) FROM c"
        }
    };
// Update the container with changes
await container.ReplaceContainerAsync(containerProperties);

Napiwek

Za każdym razem, gdy aktualizujesz właściwości kontenera, stare wartości są zastępowane. Jeśli masz już obliczone właściwości i chcesz dodać nowe, upewnij się, że do kolekcji zostały dodane zarówno nowe, jak i istniejące obliczone właściwości.

Używanie właściwości obliczonych w zapytaniach

Właściwości obliczone mogą być przywoływane w zapytaniach w taki sam sposób, w jaki są przywoływane utrwalone właściwości. Wartości właściwości obliczanych, które nie są indeksowane, są obliczane podczas wykonywania przy użyciu definicji właściwości obliczonej. Jeśli obliczona właściwość jest indeksowana, indeks jest używany w taki sam sposób, jak w przypadku utrwałych właściwości, a obliczona właściwość jest obliczana zgodnie z potrzebami. Zalecamy dodanie indeksów do obliczonych właściwości w celu uzyskania najlepszego kosztu i wydajności.

W poniższych przykładach użyto zestawu danych produktów Szybkiego startu, który jest dostępny w Eksploratorze danych w witrynie Azure Portal. Aby rozpocząć, wybierz pozycję Uruchom szybki start i załaduj zestaw danych w nowym kontenerze.

Zrzut ekranu przedstawiający sposób rozpoczęcia przewodnika Szybki start w celu załadowania przykładowego zestawu danych w witrynie Azure Portal.

Oto przykład elementu:

{
  "id": "08225A9E-F2B3-4FA3-AB08-8C70ADD6C3C2",
  "categoryId": "75BF1ACB-168D-469C-9AA3-1FD26BB4EA4C",
  "categoryName": "Bikes, Touring Bikes",
  "sku": "BK-T79U-50",
  "name": "Touring-1000 Blue, 50",
  "description": "The product called \"Touring-1000 Blue, 50\"",
  "price": 2384.07,
  "tags": [
    {
      "id": "27B7F8D5-1009-45B8-88F5-41008A0F0393",
      "name": "Tag-61"
    }
  ],
  "_rid": "n7AmAPTJ480GAAAAAAAAAA==",
  "_self": "dbs/n7AmAA==/colls/n7AmAPTJ480=/docs/n7AmAPTJ480GAAAAAAAAAA==/",
  "_etag": "\"01002683-0000-0800-0000-6451fb4b0000\"",
  "_attachments": "attachments/",
  "_ts": 1683094347
}

Projekcja

Jeśli właściwości obliczeniowe muszą być przewidywane, muszą być jawnie przywoływane. Projekcje wieloznaczne, takie jak SELECT * zwracanie wszystkich utrwalone właściwości, ale nie zawierają właściwości obliczonych.

Oto przykładowa definicja właściwości obliczonej w celu przekonwertowania name właściwości na małe litery:

{ 
  "name": "cp_lowerName", 
  "query": "SELECT VALUE LOWER(c.name) FROM c" 
} 

Ta właściwość może być następnie przewidywana w zapytaniu:

SELECT 
    c.cp_lowerName 
FROM 
    c

Klauzula WHERE

Właściwości obliczone mogą być przywoływane w predykatach filtru, takich jak wszystkie utrwalone właściwości. Zalecamy dodanie wszelkich odpowiednich indeksów pojedynczych lub złożonych podczas używania obliczonych właściwości w filtrach.

Oto przykładowa definicja obliczonej właściwości w celu obliczenia rabatu na cenę 20 procent:

{ 
  "name": "cp_20PercentDiscount", 
  "query": "SELECT VALUE (c.price * 0.2) FROM c" 
} 

Następnie można filtrować tę właściwość, aby upewnić się, że zwracane są tylko produkty, w których rabat będzie mniejszy niż 50 USD:

SELECT 
    c.price - c.cp_20PercentDiscount as discountedPrice, 
    c.name 
FROM 
    c 
WHERE 
    c.cp_20PercentDiscount < 50.00

GROUP BY, klauzula

Podobnie jak we właściwościach trwałych, właściwości obliczone mogą być przywoływane w klauzuli GROUP BY i używać indeksu zawsze, gdy jest to możliwe. Aby uzyskać najlepszą wydajność, dodaj wszystkie odpowiednie indeksy pojedyncze lub złożone.

Oto przykładowa definicja właściwości obliczonej, która znajduje kategorię podstawową dla każdego elementu z categoryName właściwości :

{
  "name": "cp_primaryCategory",
  "query": "SELECT VALUE SUBSTRING(c.categoryName, 0, INDEX_OF(c.categoryName, ',')) FROM c"
}

Następnie można grupować według cp_primaryCategory , aby uzyskać liczbę elementów w każdej kategorii podstawowej:

SELECT 
    COUNT(1), 
    c.cp_primaryCategory 
FROM 
    c 
GROUP BY 
    c.cp_primaryCategory

Napiwek

Chociaż można również osiągnąć to zapytanie bez używania właściwości obliczonych, użycie obliczonych właściwości znacznie upraszcza pisanie zapytania i umożliwia zwiększenie wydajności, ponieważ cp_primaryCategory można je indeksować. Zarówno SUBSTRING() i INDEX_OF() wymagają pełnego skanowania wszystkich elementów w kontenerze, ale jeśli zaindeksujesz obliczoną właściwość, całe zapytanie może zostać obsłużone z indeksu. Możliwość obsługi zapytania z indeksu zamiast polegania na pełnym skanowaniu zwiększa wydajność i obniża koszty jednostek żądań zapytań (RU).

Klauzula ORDER BY

Podobnie jak w przypadku trwałych właściwości, właściwości obliczone mogą być przywoływane w klauzuli ORDER BY i muszą być indeksowane, aby zapytanie powiodło się. Korzystając z obliczonych właściwości, można zamówić według wyniku złożonej logiki lub funkcji systemowych, co otwiera wiele nowych scenariuszy zapytań podczas korzystania z usługi Azure Cosmos DB.

Oto przykładowa definicja właściwości obliczonej, która pobiera miesiąc z _ts wartości:

{
  "name": "cp_monthUpdated",
  "query": "SELECT VALUE DateTimePart('m', TimestampToDateTime(c._ts*1000)) FROM c"
}

Aby można było zamówić cp_monthUpdatedwedług , należy dodać go do zasad indeksowania. Po zaktualizowaniu zasad indeksowania można zamówić według obliczonej właściwości.

SELECT
    *
FROM
    c
ORDER BY
    c.cp_monthUpdated

Właściwości obliczone indeksu

Obliczone właściwości nie są domyślnie indeksowane i nie są objęte ścieżkami wieloznacznymi w zasadach indeksowania. Indeksy pojedyncze lub złożone można dodawać do właściwości obliczonych w zasadach indeksowania w taki sam sposób, jak w przypadku dodawania indeksów dla utrwałych właściwości. Zalecamy dodanie odpowiednich indeksów do wszystkich obliczonych właściwości. Zalecamy te indeksy, ponieważ są one korzystne w zwiększaniu wydajności i zmniejszaniu liczby jednostek RU podczas indeksowania. Gdy obliczone właściwości są indeksowane, rzeczywiste wartości są oceniane podczas operacji zapisu elementu w celu generowania i utrwalania terminów indeksu.

Istnieje kilka zagadnień dotyczących indeksowania obliczonych właściwości, w tym:

  • Obliczone właściwości można określić w dołączonych ścieżkach, wykluczonych ścieżkach i ścieżkach indeksu złożonego.
  • Obliczone właściwości nie mogą mieć zdefiniowanego indeksu przestrzennego.
  • Ścieżki wieloznaczne w ramach obliczonej ścieżki właściwości działają tak jak w przypadku zwykłych właściwości.
  • Jeśli usuwasz obliczoną właściwość, która została zindeksowana, wszystkie indeksy tej właściwości również muszą zostać usunięte.

Uwaga

Wszystkie obliczone właściwości są definiowane na najwyższym poziomie elementu. Ścieżka jest zawsze /<computed property name>następująca: .

Napiwek

Za każdym razem, gdy aktualizujesz właściwości kontenera, stare wartości są zastępowane. Jeśli masz już obliczone właściwości i chcesz dodać nowe, upewnij się, że do kolekcji zostały dodane zarówno nowe, jak i istniejące obliczone właściwości.

Uwaga

Po zmodyfikowaniu definicji indeksowanej obliczonej właściwości nie jest ona automatycznie ponownie indeksowana. Aby zaindeksować zmodyfikowaną obliczoną właściwość, należy najpierw usunąć obliczoną właściwość z indeksu. Następnie po zakończeniu ponownego indeksowania dodaj obliczoną właściwość z powrotem do zasad indeksu.

Jeśli chcesz usunąć obliczoną właściwość, musisz najpierw usunąć ją z zasad indeksu.

Dodawanie pojedynczego indeksu dla obliczonych właściwości

Aby dodać pojedynczy indeks dla obliczonej właściwości o nazwie cp_myComputedProperty:

{
  "indexingMode": "consistent",
  "automatic": true,
  "includedPaths": [
    {
      "path": "/*"
    },
    {
      "path": "/cp_myComputedProperty/?"
    }
  ],
  "excludedPaths": [
    {
      "path": "/\"_etag\"/?"
    }
  ]
}

Dodawanie indeksu złożonego dla obliczonych właściwości

Aby dodać indeks złożony dla dwóch właściwości, w których jeden jest obliczany jako cp_myComputedProperty, a drugi jest utrwalany jako myPersistedProperty:

{
  "indexingMode": "consistent",
  "automatic": true,
  "includedPaths": [
    {
      "path": "/*"
    }
  ],
  "excludedPaths": [
    {
      "path": "/\"_etag\"/?"
    }
  ],
  "compositeIndexes": [
    [
      {
        "path": "/cp_myComputedProperty"
      },
      {
        "path": "/path/to/myPersistedProperty"
      }
    ]
  ]
}

Omówienie użycia jednostek żądania

Dodanie obliczonych właściwości do kontenera nie zużywa jednostek RU. Operacje zapisu na kontenerach, które mają zdefiniowane właściwości obliczeniowe, mogą mieć niewielki wzrost jednostek RU. Jeśli obliczona właściwość jest indeksowana, jednostki RU dla operacji zapisu zwiększają się w celu odzwierciedlenia kosztów indeksowania i obliczania obliczonej właściwości.