문서 메뉴
문서 홈
/ / /
C#/.NET
/

LINQ

이 페이지의 내용

  • 개요
  • 컬렉션을 쿼리 가능하게 만들기
  • 지원되는 집계 단계
  • 프로젝트
  • $매치
  • limit
  • $skip
  • $unwind
  • $그룹
  • $sort
  • $lookup
  • 지원되지 않는 애그리게이션 단계
  • 지원되는 방법

이 가이드에서는 MongoDB .NET/C# 드라이버와 함께 LINQ를 사용하는 방법을 배울 수 있습니다. LINQ를 사용하면 언어 키워드 및 연산자를 사용하여 강력한 형식의 객체 컬렉션에 대한 쿼리를 생성할 수 있습니다. .NET/C# 드라이버는 자동으로 LINQ 쿼리를 집계 작업으로 변환합니다.

이 가이드의 예제에서는 Atlas 샘플 데이터 세트 에 제공된 sample_restaurants 데이터베이스의 restaurants 컬렉션을 사용합니다. 무료 MongoDB Atlas 클러스터를 생성하고 샘플 데이터 세트를 로드하는 방법을 알아보려면 빠른 시작을 참조하세요.

다음 Restaurant, AddressGradeEntry 클래스는 이 컬렉션의 문서를 모델링합니다.

public class Restaurant
{
public ObjectId Id { get; set; }
public string Name { get; set; }
[BsonElement("restaurant_id")]
public string RestaurantId { get; set; }
public string Cuisine { get; set; }
public Address Address { get; set; }
public string Borough { get; set; }
public List<GradeEntry> Grades { get; set; }
}
public class Address
{
public string Building { get; set; }
[BsonElement("coord")]
public float[] Coordinates { get; set; }
public string Street { get; set; }
[BsonElement("zipcode")]
public string ZipCode { get; set; }
}
public class GradeEntry
{
public DateTime Date { get; set; }
public string Grade { get; set; }
public float Score { get; set; }
}

참고

restaurants 컬렉션의 문서는 카멜 케이스 명명 규칙을 사용합니다. 이 가이드의 예제에서는 ConventionPack 사용하여 컬렉션의 필드를 파스칼식 대/소문자로 역직렬화하고 Restaurant 클래스의 속성에 매핑합니다.

사용자 지정 직렬화에 대해 자세히 알아보려면 사용자 지정 직렬화를참조하세요.

LINQ를 사용하여 컬렉션을 쿼리하려면 먼저 컬렉션에 연결되는 IQueryable 객체를 만들어야 합니다. 객체를 만들려면 다음과 같이 AsQueryable() 메서드를 사용합니다.

var restaurantsCollection = restaurantsDatabase.GetCollection<Restaurant>("restaurants");
var queryableCollection = restaurantsCollection.AsQueryable();

AsQueryable() 메서드가 MongoDB 특정 메서드 세트와 함께 IQueryable 확장자 메서드를 포함하는 IMongoQueryable 인스턴스를 반환합니다.

쿼리 가능한 객체가 있으면 메서드 구문을 사용하여 쿼리를 작성할 수 있습니다. 일부 파이프라인 단계는 SQL 쿼리 구문과 유사한 쿼리 이해 구문도 지원합니다.

Method Syntax 또는 Query Syntax 탭을 선택하면 LINQ를 사용하여 쿼리를 작성하는 방법을 볼 수 있습니다.

var query = queryableCollection
.Where(r => r.Name == "The Movable Feast")
.Select(r => new { r.Name, r.Address });
var query = from r in queryableCollection
where r.Name == "The Movable Feast"
select new { r.Name, r.Address };

이전 예제의 결과를 다음과 같이 출력할 수 있습니다.

foreach (var restaurant in query)
{
Console.WriteLine(restaurant.ToJson());
}
{ "name" : "The Movable Feast", "address" : { "building" : "284", "coord" : [-73.982923900000003, 40.6580753], "street" : "Prospect Park West", "zipcode" : "11215" } }

쿼리 결과 액세스

ToList() 또는 ToCursor() 메서드를 사용하여 쿼리 결과에 액세스할 수도 있습니다:

var results = query.ToList();
var results = query.ToCursor();

LINQ를 사용하여 집계 파이프라인을 생성할 수 있습니다. .NET/C# 드라이버는 각 LINQ 구문을 해당 집계 파이프라인 단계로 자동 변환합니다. 이 섹션에서는 어떤 집계 파이프라인 단계가 지원되는지 알아볼 수 있습니다.

집계 파이프라인 단계에 대해 자세히 알아보려면 서버 매뉴얼의 집계 단계 페이지를 참조하세요.

$project 애그리게이션 단계에서는 지정된 필드만 포함된 문서를 반환합니다.

Method Syntax 또는 Query Syntax 탭을 선택하여 LINQ를 사용하여 $project 단계를 생성하는 방법을 확인합니다:

var query = queryableCollection
.Select(r => new { r.Name, r.Address });
var query = from r in queryableCollection
select new { r.Name, r.Address };

이전 예제의 결과에는 다음 문서가 포함됩니다.

{ "name" : "The Movable Feast", "address" : { "building" : "284", "coord" : [-73.982923900000003, 40.6580753], "street" : "Prospect Park West", "zipcode" : "11215" } }

참고

_id 필드 제외

LINQ 프로젝션에 _id 필드를 포함하지 않은 경우 .NET/C# 드라이버가 결과에서 자동으로 제외합니다.

$match 애그리게이션 단계에서는 지정된 기준과 일치하는 문서를 반환합니다.

Method Syntax 또는 Query Syntax 탭을 선택하여 LINQ를 사용하여 $match 단계를 생성하는 방법을 확인합니다:

var query = queryableCollection
.Where(r => r.Name == "The Movable Feast");
var query = from r in queryableCollection
where r.Name == "The Movable Feast"
select r;

이전 예제의 결과에는 다음 문서가 포함됩니다.

// Results Truncated
{ "_id" : ObjectId(...), "name" : "The Movable Feast", "restaurant_id" : "40361606", "cuisine" : "American", "address" : {...}, "borough" : "Brooklyn", "grades" : [...] }

$limit 집계 단계는 쿼리에서 반환되는 문서 수를 제한합니다. 다음 예는 LINQ를 사용하여 $limit 스테이지를 생성하는 방법을 보여 줍니다:

var query = queryableCollection
.Where(r => r.Cuisine == "Italian")
.Select(r => new {r.Name, r.Cuisine})
.Take(5);

이전 예제의 결과에는 다음 문서가 포함됩니다.

{ "name" : "Philadelhia Grille Express", "cuisine" : "Italian" }
{ "name" : "Isle Of Capri Resturant", "cuisine" : "Italian" }
{ "name" : "Marchis Restaurant", "cuisine" : "Italian" }
{ "name" : "Crystal Room", "cuisine" : "Italian" }
{ "name" : "Forlinis Restaurant", "cuisine" : "Italian" }

$skip 애그리게이션 단계에서는 쿼리에서 반환한 지정된 수의 문서를 건너뛰고 나머지 결과를 반환합니다. 다음 예는 LINQ를 사용하여 $skip 단계를 생성하는 방법을 보여 줍니다:

var query = queryableCollection
.Where(r => r.Cuisine == "Italian")
.Select(r => new {r.Name, r.Cuisine})
.Skip(2);

앞의 예에서는 기준과 일치하는 처음 두 레스토랑을 건너뛰고 나머지를 반환합니다. 결과에는 다음 문서가 포함됩니다:

// Results Truncated
{ "name" : "Marchis Restaurant", "cuisine" : "Italian" }
{ "name" : "Crystal Room", "cuisine" : "Italian" }
{ "name" : "Forlinis Restaurant", "cuisine" : "Italian" }
...

$unwind 애그리게이션 단계는 지정된 배열 필드를 분해하고 해당 배열의 각 요소에 대한 문서를 반환합니다.

Method Syntax 또는 Query Syntax 탭을 선택하면 LINQ를 사용하여 $unwind 단계를 생성하는 방법을 볼 수 있습니다.

var query = queryableCollection
.Where(r => r.Name == "The Movable Feast")
.SelectMany(r => r.Grades);
var query = from r in queryableCollection
where r.Name == "The Movable Feast"
from grade in r.Grades
select grade;

위 예의 쿼리는 Name 필드의 값이 "The Movable Feast"인 문서를 찾습니다. 그런 다음 이 문서의 Grades 배열에 있는 각 요소에 대해 쿼리는 새 문서를 반환합니다. 결과에는 다음 문서가 포함됩니다.

{ "date" : ISODate("2014-11-19T00:00:00Z"), "grade" : "A", "score" : 11 }
{ "date" : ISODate("2013-11-14T00:00:00Z"), "grade" : "A", "score" : 2 }
{ "date" : ISODate("2012-12-05T00:00:00Z"), "grade" : "A", "score" : 13 }
{ "date" : ISODate("2012-05-17T00:00:00Z"), "grade" : "A", "score" : 11 }

$group 애그리게이션 단계에서는 지정한 기준에 따라 문서를 그룹으로 분리합니다.

Method Syntax 또는 Query Syntax 탭을 선택하면 LINQ를 사용하여 $group 단계를 생성하는 방법을 볼 수 있습니다.

var query = queryableCollection
.GroupBy(r => r.Cuisine)
.Select(g => new { Cuisine = g.Key, Count = g.Count() });
var query = from r in queryableCollection
group r by r.Cuisine into g
select new {Cuisine = g.Key, Count = g.Count()};

앞의 예시에서는 각 문서를 Cuisine 필드의 값으로 그룹화한 다음 각 Cuisine 값이 있는 문서 수를 계산합니다. 결과에는 다음 문서가 포함됩니다.

// Results Truncated
{ "cuisine" : "Caribbean", "count" : 657 }
{ "cuisine" : "Café/Coffee/Tea", "count" : 1214 }
{ "cuisine" : "Iranian", "count" : 2 }
{ "cuisine" : "Nuts/Confectionary", "count" : 6 }
{ "cuisine" : "Middle Eastern", "count" : 168 }
...

참고

결과 순서

앞의 쿼리가 항상 동일한 순서로 결과를 반환하는 것은 아닙니다. 이 예제를 실행하면 위에 표시된 것과 다른 순서로 결과가 반환될 수 있습니다.

$sort 애그리게이션 단계는 지정한 순서대로 쿼리 결과를 반환합니다.

Method Syntax 또는 Query Syntax 탭을 선택하면 LINQ를 사용하여 $sort 단계를 생성하는 방법을 볼 수 있습니다.

var query = queryableCollection
.OrderBy(r => r.Name)
.ThenByDescending(r => r.RestaurantId);
var query = from r in queryableCollection
orderby r.Name, r.RestaurantId descending
select r;

위 예제에서는 Name 필드를 기준으로 알파벳순으로 정렬된 쿼리 결과를 반환하고, 2차적으로 RestaurantId 필드에서는 내림차순으로 정렬합니다. 다음은 반환된 결과에 포함된 문서의 하위 집합입니다.

// Results Truncated
...
{ "_id" : ObjectId(...), "name" : "Aba Turkish Restaurant", "restaurant_id" : "41548686", "cuisine" : "Turkish", "address" : {...}, "borough" : "Manhattan", "grades" : [...] }
{ "_id" : ObjectId(...), "name" : "Abace Sushi", "restaurant_id" : "50006214", "cuisine" : "Japanese", "address" : { ... }, "borough" : "Manhattan", "grades" : [...] }
{ "_id" : ObjectId(...), "name" : "Abacky Potluck", "restaurant_id" : "50011222", "cuisine" : "Asian", "address" : { ... }, "borough" : "Manhattan", "grades" : [...] }
{ "_id" : ObjectId(...), "name" : "Abaleh", "restaurant_id" : "50009096", "cuisine" : "Mediterranean", "address" : { ... }, "borough" : "Manhattan", "grades" : [...] }
...

$lookup 집계 단계는 한 컬렉션의 문서를 동일한 데이터베이스의 다른 컬렉션에 있는 문서와 조인합니다. $lookup 단계에서는 각 입력 문서에 새 배열 필드를 추가합니다. 새 배열 필드에는 '조인'된 컬렉션에서 일치하는 문서들이 포함됩니다.

참고

조회를 수행하려면 AsQueryable 메서드를 사용하여 두 컬렉션을 모두 쿼리할 수 있도록 설정해야 합니다.

컬렉션을 쿼리 가능하게 만드는 방법을 알아보려면 컬렉션을 쿼리 가능하게 만들기를 참조하세요.

레스토랑 리뷰가 있는 reviews라는 sample_restaurants 데이터베이스의 두 번째 컬렉션을 생각해 보세요. $lookup 단계를 사용하여 해당 컬렉션의 문서를 restaurants 컬렉션의 동일한 name 값을 가진 문서에 조인할 수 있습니다.

다음 Review 클래스는 reviews 컬렉션의 문서를 모델링합니다.

public class Review
{
public ObjectId Id { get; set; }
[BsonElement("restaurant_name")]
public string RestaurantName { get; set; }
public string Reviewer { get; set; }
[BsonElement("review_text")]
public string ReviewText { get; set; }
}

Method Syntax 또는 Query Syntax 탭을 선택하여 LINQ를 사용하여 $lookup 단계를 생성하는 방법을 확인합니다:

var query = queryableCollection
.GroupJoin(reviewCollection,
restaurant => restaurant.Name,
review => review.RestaurantName,
(restaurant, reviews) =>
new { Restaurant = restaurant, Reviews = reviews }
);
var query = from restaurant in queryableCollection
join rv in reviewCollection on restaurant.Name equals rv.RestaurantName into reviews
select new { restaurant, reviews };

앞의 예에서는 restaurants 컬렉션의 모든 문서를 반환합니다. 각 레스토랑 문서에는 해당 레스토랑에 대한 모든 리뷰가 포함된 reviews 추가 필드가 있습니다. 리뷰 문서의 name 필드 값이 레스토랑 문서의 name 필드 값과 일치하면 리뷰가 레스토랑과 일치합니다.

다음은 반환된 결과의 하위 집합입니다:

// Results Truncated
{ "restaurant" : {
"_id" : ObjectId("..."),
"name" : "The Movable Feast",
"restaurant_id" : "40361606",
"cuisine" : "American",
"address" : {...},
"borough" : "Brooklyn",
"grades" : [...] },
"reviews" : [
{ "_id" : ObjectId(...), "restaurant_name" : "The Movable Feast", "reviewer" : "Lazlo Cravensworth", "review_text" : "Great restaurant! 12/10 stars!" },
{ "_id" : ObjectId("..."), "restaurant_name" : "The Movable Feast", "reviewer" : "Michael Scarn", "review_text" : "It really was a feast" }
]
}

LINQ의 MongoDB .NET/C# 드라이버 구현은 다음 애그리게이션 단계를 지원하지 않습니다.

  • $redact

  • $geoNear

  • $out

다음은 LINQ의 MongoDB .NET/C# 드라이버 구현에서 지원되는 몇 가지 메서드입니다.

메서드 이름
설명
Any
지정된 기준과 일치하는 문서가 있는지 확인합니다.
Average
지정된 필드의 평균을 계산합니다.
Count
지정된 기준과 일치하는 문서 수를 나타내는 Int32를 반환합니다.
LongCount
지정된 기준과 일치하는 문서 수를 나타내는 Int64를 반환합니다.
Distinct
지정된 조건과 일치하는 고유한 문서를 반환합니다.
First
일치하는 첫 번째 문서를 반환하고, 일치하는 문서가 없으면 예외를 발생시킵니다.
FirstOrDefault
일치하는 첫 번째 문서를 반환하거나 일치하는 문서가 없는 경우 null을 반환합니다.
GroupBy
지정된 기준에 따라 문서 그룹화
GroupJoin
동일한 데이터베이스의 다른 컬렉션에 대한 왼쪽 외부 조인을 수행합니다.
Max
지정된 최대값을 가진 문서 반환
OfType
지정된 유형과 일치하는 문서 반환
OrderBy, OrderByDescending
지정된 정렬 순서로 결과 반환
ThenBy, ThenByDescending
세컨더리 정렬을 지정할 수 있습니다.
Select
지정된 기준에 따라 문서를 선택합니다.
SelectMany
시퀀스의 각 요소를 프로젝션하고 결과 시퀀스를 하나의 문서로 결합
Single
일치하는 문서 하나만 반환하고 문서의 개수가 하나가 아닐 경우 예외 발생
SingleOrDefault
일치하는 단일 문서를 반환하고, 일치하는 문서가 없으면 null을 반환
Skip
지정된 수의 문서를 건너뛰고 나머지 결과를 반환합니다.
Sum
지정된 필드에 있는 값의 합계 반환
Take
반환할 결과의 수 지정
Where
지정한 기준과 일치하는 모든 문서 반환

돌아가기

집계

다음

BSON 운영