Azure Cosmos DB как группировать по диапазону значений

#azure-cosmosdb #azure-cosmosdb-sqlapi

Вопрос:

У меня есть куча документов в моей базе данных Cosmos, которые имеют числовое значение, которое может варьироваться в значениях в довольно широком диапазоне. Я пытаюсь выполнить запрос group by, который группирует эти значения в пределах диапазона, который затем указывает, сколько их в каждом диапазоне.

Например, допустим, у меня есть 10 документов, и значения следующие: 1, 1, 3, 4, 6, 7, 12, 28, 70, 120

Я хочу иметь возможность группировать их так, чтобы были значения: «менее 10», «от 10 до 100» и «более 100». Я пытался написать что-то вроде приведенного ниже, но это не сработало:

 SELECT COUNT(c.TestValue > 10),
COUNT(c.TestValue <= 10 AND c.TestValue < 100),
COUNT(c.TestValue <= 100)
FROM c 
GROUP BY c.TestValue > 10,
c.TestValue <= 10 AND c.TestValue < 100,
c.TestValue <= 100
 

Очевидно, что это не работает, но я изо всех сил пытаюсь написать SQL, чтобы заставить это работать. Я делал это для какой-то другой группы по запросам, которые работали хорошо:

 SELECT TestStringValue as groupedKey,
COUNT(1) as groupedValue
FROM c
GROUP BY TestStringValue
 

Это возвращало результаты следующим образом:

 {
    "groupedKey": "Apples",
    "groupedValue": 10
}
...
 

В идеальном мире я бы хотел, чтобы результат диапазона выглядел так, как показано ниже, но я не думаю, что это возможно:

 {
    "groupedKey": "Less than 10",
    "groupedValue": 6
},
{
    "groupedKey": "Between 10 and 100",
    "groupedValue": 3
},
{
    "groupedKey": "More than 100",
    "groupedValue": 3
}
 

Комментарии:

1. Нет прямого запроса для создания подобных групп агрегации (с диапазонами). Вам нужно будет сделать это за пределами Cosmos DB, например, вернуть сгруппированные значения для каждого дискретного groupedKey , а затем самостоятельно объединить дискретные значения (или использовать потоковую службу, такую как Spark или Stream Analytics, или, возможно, хранимую процедуру, если все данные находятся в одном разделе).

Ответ №1:

Вы могли бы использовать тернарный оператор в сочетании с SUM функцией для подсчета выражения:

 SELECT 
    SUM(c.number < 10 ? 1 : 0) AS lt10,
    SUM(c.number >= 10 ? 1 : 0) AS ge10
FROM c
 

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

Тем не менее; сила Cosmos заключается в его параллельной обработке. Вы можете легко разделить свой запрос на три отдельных запроса, в которых практически не используются единицы запроса, и объединить результаты вместе.

Комментарии:

1. Можете ли вы предоставить ссылки на часть параллельной обработки? Спасибо!

2.Не совсем та же цитата, но: Azure Cosmos DB's design lets you scale to massive request volumes in the order of trillions of requests per day. docs.microsoft.com/en-us/azure/cosmos-db/use-cases