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
,_rid
i_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ść niezdefiniowaną lub null dla niektórych elementów, a obliczone właściwości z niezdefiniowanym lub null zachowują się tak samo jak właściwości utrwalone 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 c
iFROM MyContainer c
. - Zapytania muszą używać klauzuli VALUE w projekcji.
- Kwerendy nie mogą zawierać sprzężenia.
- Zapytania nie mogą używać nieokreślonych wyrażeń skalarnych. Przykłady nieokreślonych 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 (software development kit) 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.
Tworzenie obliczonych właściwości przy użyciu Eksploratora danych
Eksplorator danych umożliwia utworzenie obliczonej właściwości dla kontenera.
Otwórz istniejący kontener w Eksploratorze danych.
Przejdź do sekcji Ustawienia dla kontenera. Następnie przejdź do podsekcji *Właściwości obliczone .
Edytuj obliczoną definicję właściwości JSON dla kontenera. W tym przykładzie ten kod JSON służy do definiowania właściwości obliczonej w celu podzielenia
SKU
ciągu produktu detalicznego-
przy użyciu ogranicznika.[ { "name": "cp_splitSku", "query": "SELECT VALUE StringSplit(p.sku, \"-\") FROM products p" } ]
Zapisz obliczoną właściwość.
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.
Oto przykład elementu:
{
"id": "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb",
"categoryId": "bbbbbbbb-1111-2222-3333-cccccccccccc",
"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": "cccccccc-2222-3333-4444-dddddddddddd",
"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_monthUpdated
wedł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 żądań (RU). 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:
- Właściwości obliczane 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 ścieżce właściwości obliczonej działają tak, jakby były wykonywane dla zwykłych właściwości
- Powiązane indeksy w usuniętej i indeksowanej właściwości muszą również zostać porzucone
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.