В DocumentDB мы фактически используем SQL для запроса документов. Если мы занимаемся разработкой .NET, есть также поставщик LINQ, который можно использовать и который может генерировать соответствующий SQL из запроса LINQ.
Поддерживаемые типы данных
В DocumentDB все типы примитивов JSON поддерживаются в поставщике LINQ, включенном в DocumentDB .NET SDK, а именно:
- числовой
- логический
- строка
- Ноль
Поддерживаемое выражение
Следующие скалярные выражения поддерживаются в поставщике LINQ, входящем в состав DocumentDB .NET SDK.
-
Постоянные значения — включает постоянные значения примитивных типов данных.
-
Выражения свойства / индекса массива — выражения относятся к свойству объекта или элемента массива.
-
Арифметические выражения — включает в себя общие арифметические выражения для числовых и логических значений.
-
Выражение сравнения строк — включает сравнение строкового значения с некоторым постоянным строковым значением.
-
Выражение создания объекта / массива — возвращает объект составного типа значения или анонимного типа или массив таких объектов. Эти значения могут быть вложенными.
Постоянные значения — включает постоянные значения примитивных типов данных.
Выражения свойства / индекса массива — выражения относятся к свойству объекта или элемента массива.
Арифметические выражения — включает в себя общие арифметические выражения для числовых и логических значений.
Выражение сравнения строк — включает сравнение строкового значения с некоторым постоянным строковым значением.
Выражение создания объекта / массива — возвращает объект составного типа значения или анонимного типа или массив таких объектов. Эти значения могут быть вложенными.
Поддерживаемые операторы LINQ
Вот список поддерживаемых операторов LINQ в поставщике LINQ, включенном в DocumentDB .NET SDK.
-
Select — Проекции переводятся в SQL SELECT, включая конструкцию объекта.
-
Где — Фильтры переводят в SQL WHERE и поддерживают перевод между &&, || а также ! к операторам SQL.
-
SelectMany — позволяет разматывать массивы в предложение SQL JOIN. Может использоваться для цепочки / вложенных выражений для фильтрации элементов массива.
-
OrderBy и OrderByDescending — переводит в ORDER BY по возрастанию / убыванию.
-
CompareTo — переводит в диапазон сравнения. Обычно используется для строк, поскольку они не сопоставимы в .NET.
-
Take — переводит в SQL TOP для ограничения результатов запроса.
-
Математические функции — Поддерживает перевод из .NET Abs, Acos, Asin, Atan, Ceiling, Cos, Exp, Floor, Log, Log10, Pow, Round, Sign, Sin, Sqrt, Tan, Truncate в эквивалентные встроенные функции SQL.
-
Строковые функции — поддерживает перевод из .NET Concat, Contains, EndsWith, IndexOf, Count, ToLower, TrimStart, Replace, Reverse, TrimEnd, StartsWith, SubString, ToUpper в эквивалентные встроенные функции SQL.
-
Функции массива — поддерживает перевод из .NET Concat, Contains и Count в эквивалентные встроенные функции SQL.
-
Функции расширения геопространственных данных — Поддерживает перевод из методов-заглушек Distance, Within, IsValid и IsValidDetailed в эквивалентные встроенные функции SQL.
-
Определяемая пользователем функция расширения — Поддерживает перевод из метода-заглушки UserDefinedFunctionProvider.Invoke в соответствующую пользовательскую функцию.
-
Разное — Поддерживает перевод объединенных и условных операторов. Может переводить Contains в String CONTAINS, ARRAY_CONTAINS или SQL IN в зависимости от контекста.
Select — Проекции переводятся в SQL SELECT, включая конструкцию объекта.
Где — Фильтры переводят в SQL WHERE и поддерживают перевод между &&, || а также ! к операторам SQL.
SelectMany — позволяет разматывать массивы в предложение SQL JOIN. Может использоваться для цепочки / вложенных выражений для фильтрации элементов массива.
OrderBy и OrderByDescending — переводит в ORDER BY по возрастанию / убыванию.
CompareTo — переводит в диапазон сравнения. Обычно используется для строк, поскольку они не сопоставимы в .NET.
Take — переводит в SQL TOP для ограничения результатов запроса.
Математические функции — Поддерживает перевод из .NET Abs, Acos, Asin, Atan, Ceiling, Cos, Exp, Floor, Log, Log10, Pow, Round, Sign, Sin, Sqrt, Tan, Truncate в эквивалентные встроенные функции SQL.
Строковые функции — поддерживает перевод из .NET Concat, Contains, EndsWith, IndexOf, Count, ToLower, TrimStart, Replace, Reverse, TrimEnd, StartsWith, SubString, ToUpper в эквивалентные встроенные функции SQL.
Функции массива — поддерживает перевод из .NET Concat, Contains и Count в эквивалентные встроенные функции SQL.
Функции расширения геопространственных данных — Поддерживает перевод из методов-заглушек Distance, Within, IsValid и IsValidDetailed в эквивалентные встроенные функции SQL.
Определяемая пользователем функция расширения — Поддерживает перевод из метода-заглушки UserDefinedFunctionProvider.Invoke в соответствующую пользовательскую функцию.
Разное — Поддерживает перевод объединенных и условных операторов. Может переводить Contains в String CONTAINS, ARRAY_CONTAINS или SQL IN в зависимости от контекста.
Давайте посмотрим на пример, где мы будем использовать .Net SDK. Ниже приведены три документа, которые мы рассмотрим для этого примера.
Новый клиент 1
{ "name": "New Customer 1", "address": { "addressType": "Main Office", "addressLine1": "123 Main Street", "location": { "city": "Brooklyn", "stateProvinceName": "New York" }, "postalCode": "11229", "countryRegionName": "United States" }, }
Новый клиент 2
{ "name": "New Customer 2", "address": { "addressType": "Main Office", "addressLine1": "678 Main Street", "location": { "city": "London", "stateProvinceName": " London " }, "postalCode": "11229", "countryRegionName": "United Kingdom" }, }
Новый клиент 3
{ "name": "New Customer 3", "address": { "addressType": "Main Office", "addressLine1": "12 Main Street", "location": { "city": "Brooklyn", "stateProvinceName": "New York" }, "postalCode": "11229", "countryRegionName": "United States" }, }
Ниже приведен код, в котором мы запрашиваем с помощью LINQ. Мы определили запрос LINQ в q , но он не будет выполняться, пока мы не запустим .ToList для него.
private static void QueryDocumentsWithLinq(DocumentClient client) { Console.WriteLine(); Console.WriteLine("**** Query Documents (LINQ) ****"); Console.WriteLine(); Console.WriteLine("Quering for US customers (LINQ)"); var q = from d in client.CreateDocumentQuery<Customer>(collection.DocumentsLink) where d.Address.CountryRegionName == "United States" select new { Id = d.Id, Name = d.Name, City = d.Address.Location.City }; var documents = q.ToList(); Console.WriteLine("Found {0} US customers", documents.Count); foreach (var document in documents) { var d = document as dynamic; Console.WriteLine(" Id: {0}; Name: {1}; City: {2}", d.Id, d.Name, d.City); } Console.WriteLine(); }
SDK преобразует наш запрос LINQ в синтаксис SQL для DocumentDB, генерируя предложение SELECT и WHERE на основе нашего синтаксиса LINQ.
Давайте вызовем вышеупомянутые запросы из задачи CreateDocumentClient.
private static async Task CreateDocumentClient() { // Create a new instance of the DocumentClient using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) { database = client.CreateDatabaseQuery("SELECT * FROM c WHERE c.id = 'myfirstdb'").AsEnumerable().First(); collection = client.CreateDocumentCollectionQuery(database.CollectionsLink, "SELECT * FROM c WHERE c.id = 'MyCollection'").AsEnumerable().First(); QueryDocumentsWithLinq(client); } }
Когда приведенный выше код выполняется, он производит следующий вывод.