«Новый» макет индекса
Как указано в Типы индекса
Контейнеры Azure Cosmos поддерживают новый макет индекса, который больше не использует вид индекса Hash,Если вы зададите тип индекса Hash в политике индексирования, запросы CRUD для контейнера будут автоматически игнорировать тип индекса, а ответ от контейнера будет содержать только вид индекса Range.Все новые контейнеры Cosmos используют новую компоновку индекса по умолчанию.
Следующая проблема не относится к для новой компоновки индекса.Там политика индексации по умолчанию работает нормально (и выдает результаты в 36.55 RUs
).Однако в уже существующих коллекциях все еще может использоваться старый макет.
«Старый» макет индекса
Мне удалось воспроизвести проблему с ARRAY_CONTAINS
, о которой вы спрашиваете.
Настройка коллекции CosmosDB с 100 000 сообщений из дампа данных SO (например, этот вопрос будет представлен ниже)
{
"id": "50614926",
"title": "Indexing arrays in CosmosDB",
/*Other irrelevant properties omitted */
"tags": [
"azure",
"azure-cosmosdb"
]
}
И затем выполнение следующего запроса
SELECT COUNT(1)
FROM t IN c.tags
WHERE t = 'sql-server'
На запрос ушло более 2000 RU с политикой индексирования по умолчанию и 93 со следующим дополнением (как показано в вашей связанной статье)
{
"path": "/tags/[]/?",
"indexes": [
{
"kind": "Hash",
"dataType": "String",
"precision": -1
}
]
}
Однако вы видите , а не , что массивзначения не индексируются по умолчанию.Просто индекс диапазона по умолчанию бесполезен для вашего запроса.
В индексе диапазона используются ключи, основанные на частичных прямых путях.Так будет содержать пути, такие как следующие.
tags/0/azure
tags/0/c#
tags/0/oracle
tags/0/sql-server
tags/1/azure-cosmosdb
tags/1/c#
tags/1/sql-server
При такой структуре индекса она начинается с tags/0/sql-server
и затем считывает всеоставшиеся tags/0/
записей и полные записи для tags/n/
, где n
является целым числом, превышающим 0
.Каждый отдельный документ, сопоставленный с любым из них, должен быть извлечен и оценен.
В отличие от хеш-индекса используются обратные пути ( больше подробностей - PDF )
Теоретически позволяет StackOverflowмаксимум 5 тегов на вопрос, которые будут добавлены пользовательским интерфейсом, поэтому в этом случае (игнорируя тот факт, что несколько вопросов имеют больше тегов в действиях администратора сайта), обратные интересующие пути составляют
sql-server/0/tags
sql-server/1/tags
sql-server/2/tags
sql-server/3/tags
sql-server/4/tags
С обратным путемСтруктура поиска всех путей с конечными узлами значения sql-server проста.
В этом конкретном случае использования, поскольку массивы ограничены максимум 5 возможными значениями, также возможно эффективно использовать исходный индекс диапазонаглядя только на эти конкретные пути.
Следующий запрос потребовал 97 RU с политикой индексации по умолчанию в моей тестовой коллекции.
SELECT COUNT(1)
FROM c
WHERE 'sql-server' IN (c.tags[0], c.tags[1], c.tags[2], c.tags[3], c.tags[4])