Коллекции кросс-JOIN и API Javascript для GroupBy CosmosDB
Я ищу решение в API Javascript для CosmosDB, где вы можете выполнить INNER/OUTER JOIN между двумя коллекциями документов.
Я был неудачным.
Насколько я понимаю, хранимые процедуры Javascript выполняются внутри коллекции и не могут обращаться к данным в другой коллекции или ссылаться на них.
Если вышеприведенное верно, где это оставляет источник данных нашего приложения, который был разработан реляционным способом? Если Бизнес требует немедленного запроса, соберите следующие данные: Все соглашения / контракты, которые были перенесены в новое предложение продукта в пределах определенного региона в течение определенного периода времени. Как мне поступить с этим запросом, если существует около 5 коллекций, содержащих всю информацию, связанную с этим запросом?
Любое руководство?
ОБНОВИТЬ
Покупатель
{
"id": "d02e6668-ce24-455d-b241-32835bb2dcb5",
"Name": "Test User One",
"Surname": "Test"
}
соглашение
{
"id": "ee1094bd-16f4-45ec-9f5e-7ecd91d4e729",
"CustomerId": "d02e6668-ce24-455d-b241-32835bb2dcb5"
"RetailProductVersionInstance":
[
{
"id": "8ce31e7c-7b1a-4221-89a3-449ae4fd6622",
"RetailProductVersionId": "ce7a44a4-7e49-434b-8a51-840599fbbfbb",
"AgreementInstanceUser": {
"FirstName": "Luke",
"LastName": "Pothier",
"AgreementUserTypeId": ""
},
"AgreementInstanceMSISDN": {
"IsoCountryDialingCode": null,
"PhoneNumber": "0839263922",
"NetworkOperatorId": "30303728-9983-47f9-a494-1de853d66254"
},
"RetailProductVersionInstanceState": "IN USE",
"IsPrimaryRetailProduct": true,
"RetailProductVersionInstancePhysicalItems": [
{
"id": "f8090aba-f06b-4233-9f9e-eb2567a20afe",
"PhysicalItemId": "75f64ab3-81d2-f600-6acb-d37da216846f",
"RetailProductVersionInstancePhysicalItemNumbers": [
{
"id": "9905058b-8369-4a64-b9a5-e17e28750fba",
"PhysicalItemNumberTypeId": "39226b5a-429b-4634-bbce-2213974e5bab",
"PhysicalItemNumberValue": "KJDS959405"
},
{
"id": "1fe09dd2-fb8a-49b3-99e6-8c51df10adb1",
"PhysicalItemNumberTypeId": "960a1750-64be-4333-9a7f-c8da419d670a",
"PhysicalItemNumberValue": "DJDJ94943"
}
],
"RetailProductVersionInstancePhysicalItemState": "IN USE",
"DateCreatedUtc": "2018-11-21T13:55:00Z",
"DateUpdatedUtc": "2020-11-21T13:55:00Z"
}
]
}
]
}
RetailProduct
{
"id": "ce7a44a4-7e49-434b-8a51-840599fbbfbb",
"FriendlyName": "Data-Package 100GB",
"WholeSaleProductId": "d054dae5-173d-478b-bb0e-7516e6a24476"
}
WholeSaleProduct:
{
"id": "d054dae5-173d-478b-bb0e-7516e6a24476",
"ProductName": "Data 100",
"ProviderLiabilities": []
}
Выше я добавил образец документации.
Отношения:
- Agreement.CustomerId ссылки на Customer.id
- Agreement.RetailProductVersionInstance.RetailProductVersionId ссылается на RetailProduct.id
- RetailProduct.WholeSaleProductId ссылки на WholeSaleProduct.id
Как бы я написал хранимую процедуру Javascript в CosmosDB для выполнения объединений между этими 4 коллекциями?
1 ответ
Короткий ответ: вы не можете выполнять соединения между различными коллекциями через SQL в Cosmos DB.
Как правило, решение этого типа вопроса - несколько запросов или другая схема. В вашем сценарии, если вы можете денормализовать вашу схему в одну коллекцию без дублирования данных, тогда это легко.
Если вы предоставите свои схемы, можно будет дать более полный ответ.
- Правка 1 -
Хранимые процедуры являются хорошими кандидатами для операций, требующих нескольких операций над одной коллекцией + ключом раздела. Это делает их хорошими для массовой вставки / удаления / обновления, транзакций (которые требуют, по крайней мере, чтения и записи) и некоторых других вещей. Они не подходят для ресурсоемких задач, а скорее для вещей, которые обычно связаны с задержкой ввода-вывода. Их невозможно использовать для сценариев перекрестного разделения или перекрестного сбора. В этих случаях вы должны выполнять операции исключительно с удаленного клиента.
В вашем случае это довольно просто 2 + 2N
отдельные чтения, где N
количество продуктов Вы должны сначала прочитать соглашение. Затем вы можете параллельно просматривать записи о клиентах и продуктах, а затем вы можете просматривать последние записи об оптовых продажах, поэтому у вас должна быть задержка 3s + C
, где s
средняя продолжительность данного запроса на чтение и C
некоторое постоянное время процессора для выполнения соединения / выдачи запроса / и т.д.
Стоит подумать о том, можете ли вы объединить RetailProduct и WholeSale в одну запись, где Wholesale содержит все RetailProducts в массиве, или в виде отдельных документов, разделенных по оптовому идентификатору, с хорошо известным идентификатором, содержащим информацию об оптовом продукте в отдельной документ. Это уменьшит вашу задержку на 1 треть. Если вы идете с разделением по идее оптового идентификатора, вы можете написать 1 запрос для любых записей, которые имеют оптовый идентификатор, так что вы получите 2 + log(N)
читает, но та же эффективная задержка. Для этой стратегии вы должны хранить составной индекс "wholesaleid +productid" в соглашении. Одной из проблем, о которой следует беспокоиться, является то, что они дублируют отношения "оптовый + товар", но пока эти отношения не меняются, я не думаю, что есть о чем беспокоиться, и это обеспечивает хорошую оптимизацию для поиска информации.