Azure Cosmos DB for NoSQL での LINQ から NoSQL への変換
適用対象: NoSQL
Azure Cosmos DB クエリ プロバイダーは、LINQ クエリから Azure Cosmos DB for NoSQL クエリへのマッピングをベスト エフォートで実行します。 LINQ から変換される NoSQL クエリを取得する場合、生成された IQueryable
オブジェクトで ToString()
メソッドを使用します。 以下の説明では、LINQ の基本的知識を前提としています。 LINQ に加えて、Azure Cosmos DB では、NoSQL 用 API と連携する Entity Framework Core もサポートされます。
Note
最新の .NET SDK (Microsoft.Azure.Cosmos
) バージョンを使用することをお勧めします
クエリ プロバイダーの型システムでは、JSON プリミティブ型 (numeric
、Boolean
、string
、および null
) のみがサポートされます。
クエリ プロバイダーでは、以下のスカラー式がサポートされます。
定数値。クエリ評価時のプリミティブ データ型の定数値を含みます。
プロパティ/配列インデックス式。オブジェクトまたは配列要素のプロパティを参照します。 次に例を示します。
family.Id; family.children[0].familyName; family.children[0].grade;
int n = 1; family.children[n].grade;
算術式。数値およびブール値に対する共通の算術式を含みます。
2 * family.children[0].grade; x + y;
文字列比較式。これは、文字列値と定数文字列値との比較を含みます。
mother.familyName.StringEquals("Wakefield");
string s = "Rob"; string e = "in"; string c = "obi"; child.givenName.StartsWith(s); child.givenName.EndsWith(e); child.givenName.Contains(c);
オブジェクト/配列作成式。複合値の型または匿名型のオブジェクト、またはこうしたオブジェクトの配列を返します。 これらの値は入れ子にすることができます。
new Parent { familyName = "Wakefield", givenName = "Robin" }; new { first = 1, second = 2 }; //an anonymous type with two fields new int[] { 3, child.grade, 5 };
LINQ を使用する
GetItemLinqQueryable
を使用して LINQ クエリを作成できます。 この例では、FeedIterator
を使用した LINQ クエリの生成と非同期実行を示します。
using FeedIterator<Book> setIterator = container.GetItemLinqQueryable<Book>()
.Where(b => b.Title == "War and Peace")
.ToFeedIterator<Book>());
//Asynchronous query execution
while (setIterator.HasMoreResults)
{
foreach(var item in await setIterator.ReadNextAsync()){
{
Console.WriteLine(item.cost);
}
}
サポートされている LINQ 演算子
NoSQL .NET SDK に含まれる LINQ プロバイダーでは、次の演算子がサポートされています。
- Select:オブジェクトの構築など、プロジェクションによって SELECT に変換します。
- Where: フィルターによって WHERE に変換します。また、
&&
、||
、および!
から NoSQL 演算子への変換をサポートしています - SelectMany:JOIN 句に対して配列をアンワインドできます。 配列要素に関してフィルターする式を連結または入れ子にするために使用します。
- OrderBy と OrderByDescending:ASC または DESC で ORDER BY に変換します。
- 集計のための Count、Sum、Min、Max、Average 演算子と非同期でそれに相当する CountAsync、SumAsync、MinAsync、MaxAsync、AverageAsync 演算子。
- CompareTo:範囲比較に変換します。 これらの演算子は .NET では比較できないので、一般的に文字列に使用されます。
- Skip と Take:クエリからの結果を制限して改ページ位置の自動修正を実行するために、OFFSET および LIMIT に変換されます。
- 数学関数:.NET
Abs
、Acos
、Asin
、Atan
、Ceiling
、Cos
、Exp
、Floor
、Log
、Log10
、Pow
、Round
、Sign
、Sin
、Sqrt
、Tan
、およびTruncate
から同等の組み込み数学関数への変換をサポートします。 - 文字列関数:.NET
Concat
、Contains
、Count
、EndsWith
,IndexOf
、Replace
、Reverse
、StartsWith
、SubString
、ToLower
、ToUpper
、TrimEnd
、およびTrimStart
から同等の組み込み文字列関数への変換をサポートします。 - 配列関数:.NET
Concat
、Contains
、およびCount
から同等の組み込み配列関数への変換をサポートします。 - 地理空間の拡張関数:スタブ メソッド
Distance
、IsValid
、IsValidDetailed
、およびWithin
から同等の組み込み地理空間関数への変換をサポートします。 - ユーザー定義関数の拡張関数: スタブ メソッド CosmosLinq.InvokeUserDefinedFunction から、対応するユーザー定義関数への変換をサポートします。
- その他:
Coalesce
と条件演算子の変換をサポートします。 コンテキストに応じて、Contains
から、文字列 CONTAINS、ARRAY_CONTAINS、または IN に変換できます。
例
一部の標準 LINQ クエリ演算子が Azure Cosmos DB のクエリにどのように変換されるかを以下の例で示します。
Select 演算子
構文は input.Select(x => f(x))
です。f
はスカラー式です。 この場合、input
は IQueryable
オブジェクトになります。
Select 演算子、例 1:
LINQ ラムダ式
input.Select(family => family.parents[0].familyName);
NoSQL
SELECT VALUE f.parents[0].familyName FROM Families f
Select 演算子、例 2:
LINQ ラムダ式
input.Select(family => family.children[0].grade + c); // c is an int variable
NoSQL
SELECT VALUE f.children[0].grade + c FROM Families f
Select 演算子、例 3:
LINQ ラムダ式
input.Select(family => new { name = family.children[0].familyName, grade = family.children[0].grade + 3 });
NoSQL
SELECT VALUE { "name":f.children[0].familyName, "grade": f.children[0].grade + 3 } FROM Families f
SelectMany 演算子
構文は input.SelectMany(x => f(x))
です。f
はコンテナー型を返すスカラー式です。
LINQ ラムダ式
input.SelectMany(family => family.children);
NoSQL
SELECT VALUE child FROM child IN Families.children
Where 演算子
構文は input.Where(x => f(x))
です。f
は Boolean 値を返すスカラー式です。
Where 演算子、例 1:
LINQ ラムダ式
input.Where(family=> family.parents[0].familyName == "Wakefield");
NoSQL
SELECT * FROM Families f WHERE f.parents[0].familyName = "Wakefield"
Where 演算子、例 2:
LINQ ラムダ式
input.Where( family => family.parents[0].familyName == "Wakefield" && family.children[0].grade < 3);
NoSQL
SELECT * FROM Families f WHERE f.parents[0].familyName = "Wakefield" AND f.children[0].grade < 3
複合 NoSQL クエリ
上記の演算子を組み合わせて、より強力なクエリを作成できます。 Azure Cosmos DB では入れ子になったコンテナーがサポートされるため、複合を連結または入れ子にできます。
連結
構文は input(.|.SelectMany())(.Select()|.Where())*
です。 連結クエリは、オプションの SelectMany
クエリで開始し、複数の Select
または Where
演算子を追加できます。
連結、例 1:
LINQ ラムダ式
input.Select(family => family.parents[0]) .Where(parent => parent.familyName == "Wakefield");
NoSQL
SELECT * FROM Families f WHERE f.parents[0].familyName = "Wakefield"
連結、例 2:
LINQ ラムダ式
input.Where(family => family.children[0].grade > 3) .Select(family => family.parents[0].familyName);
NoSQL
SELECT VALUE f.parents[0].familyName FROM Families f WHERE f.children[0].grade > 3
連結、例 3:
LINQ ラムダ式
input.Select(family => new { grade=family.children[0].grade}). Where(anon=> anon.grade < 3);
NoSQL
SELECT * FROM Families f WHERE ({grade: f.children[0].grade}.grade > 3)
連結、例 4:
LINQ ラムダ式
input.SelectMany(family => family.parents) .Where(parent => parents.familyName == "Wakefield");
NoSQL
SELECT * FROM p IN Families.parents WHERE p.familyName = "Wakefield"
入れ子
構文は input.SelectMany(x=>x.Q())
です。Q
は Select
、SelectMany
、または Where
演算子です。
入れ子になったクエリは、内側のクエリを外側のコンテナーの各要素に適用します。 1 つの重要な機能として、内側のクエリは外側のコンテナーの要素のフィールドを自己結合のように参照できます。
入れ子、例 1:
LINQ ラムダ式
input.SelectMany(family=> family.parents.Select(p => p.familyName));
NoSQL
SELECT VALUE p.familyName FROM Families f JOIN p IN f.parents
入れ子、例 2:
LINQ ラムダ式
input.SelectMany(family => family.children.Where(child => child.familyName == "Jeff"));
NoSQL
SELECT * FROM Families f JOIN c IN f.children WHERE c.familyName = "Jeff"
入れ子、例 3:
LINQ ラムダ式
input.SelectMany(family => family.children.Where( child => child.familyName == family.parents[0].familyName));
NoSQL
SELECT * FROM Families f JOIN c IN f.children WHERE c.familyName = f.parents[0].familyName