Бөлісу құралы:


Вычисляемых свойств в Azure Cosmos DB для NoSQL

ОБЛАСТЬ ПРИМЕНЕНИЯ: NoSQL

Вычисляемые свойства в Azure Cosmos DB имеют значения, производные от существующих свойств элемента, но свойства не сохраняются в самих элементах. Вычисляемые свойства относятся к одному элементу и могут ссылаться на запросы, как если бы они были сохранены. Вычислимые свойства упрощают запись сложной логики запросов один раз и много раз ссылаются на нее. Вы можете добавить один индекс к этим свойствам или использовать их в составе составного индекса для повышения производительности.

Примечание.

У вас есть отзывы о вычисляемых свойствах? Нам очень интересно ваше мнение! Вы можете поделиться отзывами напрямую с командой инженеров Azure Cosmos DB. cosmoscomputedprops@microsoft.com

Что такое вычисляемое свойство?

Вычисляемые свойства должны находиться на верхнем уровне элемента и не могут содержать вложенный путь. Каждое определение вычисляемого свойства имеет два компонента: имя и запрос. Это имя вычисляемого свойства, и запрос определяет логику для вычисления значения свойства для каждого элемента. Вычисляемые свойства относятся к отдельному элементу и поэтому не могут использовать значения из нескольких элементов или полагаться на другие вычисляемые свойства. Каждый контейнер может иметь не более 20 вычисляемых свойств.

Пример определения вычисляемого свойства:

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

Ограничения имен

Настоятельно рекомендуется присвоить вычисляемые свойства, чтобы не было конфликтов с сохраненным именем свойства. Чтобы избежать перекрывающихся имен свойств, можно добавить префикс или суффикс ко всем вычисляемых именам свойств. В этой статье используется префикс cp_ во всех определениях имен.

Внимание

Определение вычисляемого свойства с помощью того же имени, что и сохраненное свойство, не приводит к ошибке, но может привести к неожиданному поведению. Независимо от того, индексируется ли вычисляемое свойство, значения из сохраняемых свойств, которые совместно используют имя с вычисляемым свойством, не будут включаться в индекс. Запросы всегда будут использовать вычисляемое свойство вместо сохраняемого, за исключением случаев, когда вместо вычисляемого возвращается сохраняемое свойство, если в предложении SELECT есть проекция с подстановочными знаками. Проекция подстановочных знаков не включает автоматически вычисляемые свойства.

Ограничения для вычисляемых имен свойств:

  • Все вычисляемые свойства должны иметь уникальные имена.
  • Значение name свойства представляет имя свойства верхнего уровня, которое можно использовать для ссылки на вычисляемое свойство.
  • Зарезервированные имена системных свойств, например id, _ridи _ts не могут использоваться в качестве вычисляемых имен свойств.
  • Имя вычисляемого свойства не может соответствовать пути к свойству, который уже индексирован. Это ограничение применяется ко всем указанным путям индексирования, включая:
    • Включенные пути
    • Исключенные пути
    • Пространственные индексы
    • Составные индексы

Ограничения запросов

Запросы в определении вычисляемого свойства должны быть допустимыми синтаксически и семантично, в противном случае операция создания или обновления завершается ошибкой. Запросы должны оцениваться детерминированным значением для всех элементов в контейнере. Запросы могут оцениваться как неопределенные или null для некоторых элементов, а вычисляемые свойства с неопределенными или пустыми значениями ведут себя так же, как и сохраненные свойства с неопределенными или пустыми значениями при использовании в запросах.

Ограничения для определений запросов вычисляемых свойств:

  • Запросы должны указывать предложение FROM, представляющее ссылку на корневой элемент. Примеры поддерживаемых предложений FROM: FROM c, FROM root cи FROM MyContainer c.
  • Запросы должны использовать предложение VALUE в проекции.
  • Запросы не могут содержать JOIN.
  • Запросы не могут использовать недетерминированные скалярные выражения. Примерами недетерминированных скалярных выражений являются GetCurrentDateTime, GetCurrentTimeStamp, GetCurrentTicks и RAND.
  • Запросы не могут использовать одно из следующих предложений: WHERE, GROUP BY, ORDER BY, TOP, DISTINCT, OFFSET LIMIT, EXISTS, ALL, LAST, FIRST и NONE.
  • Запросы не могут содержать скалярный вложенный запрос.
  • Агрегатные функции, пространственные функции, недетерминированные функции и определяемые пользователем функции (ОПРЕДЕЛ) не поддерживаются.

Создание вычисляемых свойств

После создания вычисляемых свойств можно выполнять запросы, ссылающиеся на свойства с помощью любого метода, включая все пакеты SDK и Azure Data Explorer в портал Azure.

Поддерживаемая версия Примечания.
Пакет SDK версии 3 для .NET >= 3.34.0-preview Вычисляемые свойства в настоящее время доступны только в предварительных версиях пакетов.
Пакет SDK для Java версии 4 >= 4.46.0 Вычисляемые свойства в настоящее время находятся в предварительной версии.
Пакет SDK для Python >= v4.5.2b5 Вычисляемые свойства в настоящее время находятся в предварительной версии.

Создание вычисляемых свойств с помощью пакета SDK

Можно создать новый контейнер с определенными вычисляемыми свойствами или добавить вычисляемые свойства в существующий контейнер.

Ниже приведен пример создания вычисляемых свойств в новом контейнере:

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);

Ниже приведен пример обновления вычисляемых свойств в существующем контейнере:

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);

Совет

При каждом обновлении свойств контейнера старые значения перезаписываются. Если у вас есть вычисляемые свойства и хотите добавить новые, убедитесь, что в коллекцию добавлены новые и существующие вычисляемые свойства.

Создание вычисляемых свойств с помощью обозревателя данных

Обозреватель данных можно использовать для создания вычисляемого свойства для контейнера.

  1. Откройте существующий контейнер в обозревателе данных.

  2. Перейдите к разделу "Параметры " для контейнера. Затем перейдите к подразделу *Вычисляемых свойств .

  3. Измените вычисляемое определение свойств JSON для контейнера. В этом примере этот JSON используется для определения вычисляемого свойства для разделения SKU строки для розничного продукта с помощью - разделителя.

    [
      {
        "name": "cp_splitSku",
        "query": "SELECT VALUE StringSplit(p.sku, \"-\") FROM products p"
      }
    ]
    

    Снимок экрана: редактор вычисляемых свойств JSON в интерфейсе Обозревателя данных.

  4. Сохраните вычисляемое свойство.

Использование вычисляемых свойств в запросах

Вычисляемые свойства можно ссылаться в запросах так же, как и на сохраненные свойства. Значения вычисляемых свойств, которые не индексируются, оцениваются во время выполнения с помощью определения вычисляемого свойства. Если вычисляемое свойство индексируется, индекс используется так же, как он используется для сохраненных свойств, и вычисляемое свойство вычисляется по мере необходимости. Рекомендуется добавлять индексы в вычисляемые свойства для оптимальной стоимости и производительности.

В следующих примерах используется набор данных продуктов быстрого запуска, доступный в обозревателе данных в портал Azure. Чтобы приступить к работе, нажмите кнопку "Запустить быстрый запуск " и загрузите набор данных в новом контейнере.

Снимок экрана: загрузка примера набора данных в базу данных и контейнер.

Ниже приведен пример элемента:

{
  "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
}

Проекция

Если вычисляемые свойства необходимо проецировать, они должны быть явно ссылаться на них. Проекции подстановочных знаков, такие как SELECT * возврат всех сохраненных свойств, но не включают вычисляемые свойства.

Ниже приведен пример определения вычисляемого свойства для преобразования свойства в name нижний регистр:

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

Затем это свойство можно проецировать в запросе:

SELECT 
    c.cp_lowerName 
FROM 
    c

Предложение WHERE

Вычисляемые свойства можно ссылаться на предикаты фильтра, как и любые сохраненные свойства. При использовании вычисляемых свойств в фильтрах рекомендуется добавлять все соответствующие один или составные индексы.

Ниже приведен пример определения вычисляемого свойства для вычисления 20 процентов скидки на цену:

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

Затем это свойство можно отфильтровать, чтобы убедиться, что возвращаются только продукты, в которых скидка будет меньше $ 50:

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

Предложение GROUP BY

Как и в случае с сохраненными свойствами, вычисляемые свойства можно ссылаться в предложении GROUP BY и использовать индекс по возможности. Чтобы повысить производительность, добавьте все соответствующие один или составные индексы.

Ниже приведен пример определения вычисляемого свойства, которое находит основную категорию для каждого элемента из categoryName свойства:

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

Затем можно сгруппировать cp_primaryCategory , чтобы получить количество элементов в каждой основной категории:

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

Совет

Хотя этот запрос можно также достичь без использования вычисляемых свойств, используя вычисляемые свойства, значительно упрощает написание запроса и позволяет повысить производительность, так как cp_primaryCategory их можно индексировать. Как SUBSTRING(), так и INDEX_OF() требуют полного сканирования всех элементов в контейнере, но если индексировать вычисляемое свойство, то весь запрос можно обслуживать из индекса. Возможность обслуживать запрос из индекса вместо того, чтобы полагаться на полную проверку, повышает производительность и снижает затраты на единицу запросов (ЕЗ).

Предложение ORDER BY

Как и в случае с сохраненными свойствами, вычисляемые свойства можно ссылаться в предложении ORDER BY, и их необходимо индексировать для успешного выполнения запроса. Используя вычисляемые свойства, вы можете УПОРЯДОЧИТЬ РЕЗУЛЬТАТ сложных логики или системных функций, что открывает множество новых сценариев запросов при использовании Azure Cosmos DB.

Ниже приведен пример определения вычисляемого свойства, которое получает месяц из _ts значения:

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

Прежде чем вы сможете ЗАКАЗАТЬ BY cp_monthUpdated, необходимо добавить его в политику индексирования. После обновления политики индексирования можно упорядочить с помощью вычисляемого свойства.

SELECT
    *
FROM
    c
ORDER BY
    c.cp_monthUpdated

Вычисляемый индекс свойств

Вычисляемые свойства по умолчанию не индексируются и не охватываются подстановочными знаками в политике индексирования. Вы можете добавить один или составные индексы для вычисляемых свойств в политике индексирования так же, как и индексы для сохраненных свойств. Рекомендуется добавлять соответствующие индексы ко всем вычисляемых свойствам. Мы рекомендуем эти индексы, так как они полезны для повышения производительности и уменьшения единиц запросов (ЕЗ). При индексировании вычисляемых свойств фактические значения оцениваются во время операций записи элементов для создания и сохранения терминов индекса.

Существует несколько рекомендаций по индексации вычисляемых свойств, в том числе:

  • Вычисляемые свойства можно указать в включенных путях, исключенных путях и составных путях индекса.
  • Вычисляемые свойства не могут иметь пространственный индекс, определенный на них
  • Пути подстановочных знаков в пути вычисляемого свойства работают так, как они выполняются для обычных свойств
  • Связанные индексы для удаленного и индексированного свойства также должны быть удалены

Примечание.

Все вычисляемые свойства определяются на верхнем уровне элемента. Путь всегда /<computed property name>.

Совет

При каждом обновлении свойств контейнера старые значения перезаписываются. Если у вас есть вычисляемые свойства и хотите добавить новые, убедитесь, что в коллекцию добавлены новые и существующие вычисляемые свойства.

Примечание.

При изменении определения индексированного вычисляемого свойства он не будет автоматически переиндексирован. Чтобы индексировать измененное вычисляемое свойство, сначала необходимо удалить вычисляемое свойство из индекса. Затем после завершения повторной индексации добавьте вычисляемое свойство обратно в политику индекса.

Если вы хотите удалить вычисляемое свойство, сначала необходимо удалить его из политики индекса.

Добавление одного индекса для вычисляемых свойств

Добавление одного индекса для вычисляемого свойства с именем cp_myComputedProperty:

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

Добавление составного индекса для вычисляемых свойств

Чтобы добавить составной индекс на два свойства, в которых вычисляется один как cp_myComputedProperty, а другой сохраняется как myPersistedProperty:

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

Общие сведения о потреблении единиц запросов

Добавление вычисляемых свойств в контейнер не потребляет ЕЗ. Операции записи в контейнерах с вычисляемыми свойствами могут иметь небольшое увеличение ЕЗ. Если вычисляемое свойство индексируется, ЕЗ при операциях записи увеличивается, чтобы отразить затраты на индексирование и оценку вычисляемого свойства.