Cosmos DB(Azure 및 패브릭) 쿼리 공급자는 효율적인 데이터 검색을 위해 LINQ(언어 통합 쿼리)를 NoSQL 쿼리로 변환합니다. 이 문서에서는 지원되는 LINQ 연산자와 LINQ 쿼리가 Cosmos DB 구문에 매핑되어 .NET 개발자가 데이터베이스 쿼리를 최적화하는 데 도움이 되는 방법을 설명합니다. LINQ 코드에서 번역된 NoSQL 쿼리를 보려면 생성된 IQueryable 개체의 ToString() 메서드를 사용합니다. 다음 설명에서는 LINQ에 대한 기본적인 지식이 있다고 가정합니다. LinQ 외에도 Cosmos DB는 NoSQL용 API와 함께 작동하는 Entity Framework Core도 지원합니다.
비고
최신 .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 사용
를 사용하여 LINQ 쿼리 GetItemLinqQueryable를 만들 수 있습니다. 이 예제에서는 다음을 사용하여 LINQ 쿼리 생성 및 비동기 실행을 보여 줍니다.FeedIterator
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변환됩니다. -
위치: 필터가 변환되고
WHERE,||!및 NoSQL 연산자 간&&변환을 지원합니다. -
SelectMany: 절에 대한 배열 해제를
JOIN허용합니다. 배열 요소를 필터링하기 위해 식을 연결하거나 중첩하는 데 사용합니다. -
OrderBy 및 OrderByDescending: 와 함께 또는
DESC.ASC로ORDER BY변환 - 집계에 대한 Count, Sum, Min, Max 및 Average 연산자 및 해당 비동기 연산자는 CountAsync, SumAsync, MinAsync, MaxAsync 및 AverageAsync에 해당합니다.
- CompareTo: 범위 비교로 변환합니다. 이 연산자는 .NET에서 비교할 수 없으므로 문자열에 일반적으로 사용됩니다.
-
건너뛰기 및 사용: 쿼리의 결과를 제한하고
LIMIT페이지 매김을 수행하도록 변환OFFSET합니다. -
수학 함수: .NET
Abs, ,Acos, ,Asin,Atan,Ceiling,CosFloorLogExp,Log10, ,Pow,TanSinSignSqrtRound및Truncate동등한 기본 제공 수학 함수로의 번역을 지원합니다. -
문자열 함수: .NET
Concat, , ,Contains,Count,IndexOfEndsWithReplaceToLowerTrimEndSubStringStartsWithToUpperReverse및TrimStart해당하는 기본 제공 문자열 함수로의 변환을 지원합니다. -
배열 함수: .NET
ConcatContainsCount에서 동일한 기본 제공 배열 함수로의 변환을 지원합니다. -
지리 공간적 확장 함수: 스텁 메서드
DistanceIsValidIsValidDetailed, 및Within해당하는 기본 제공 지리 공간적 함수로의 변환을 지원합니다. -
User-Defined 함수 확장 함수: 스텁 메서드
CosmosLinq.InvokeUserDefinedFunction에서 해당 사용자 정의 함수로의 변환을 지원합니다. -
기타: 조건부 연산자의
Coalesce변환을 지원합니다. 컨텍스트에 따라 문자열CONTAINS또는ARRAY_CONTAINSIN문자열로 변환Contains할 수 있습니다.
예시
다음 예제에서는 일부 표준 LINQ 쿼리 연산자가 Cosmos DB의 쿼리로 변환되는 방법을 보여 줍니다.
연산자 선택
구문은 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 variableNoSQL
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 부울 값을 반환하는 스칼라 식입니다.
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 쿼리
이전 연산자를 작성하여 더 강력한 쿼리를 구성할 수 있습니다. 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 , SelectMany또는 Where 연산자입니다Select.
중첩된 쿼리는 외부 컨테이너의 각 요소에 내부 쿼리를 적용합니다. 한 가지 중요한 기능은 내부 쿼리가 자체 조인과 같이 외부 컨테이너의 요소 필드를 참조할 수 있다는 것입니다.
중첩, 예제 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