Docs Menu
Docs Home
/ / /
C#/.NET
/

LINQ

項目一覧

  • Overview
  • コレクションをクエリ可能にします
  • サポートされている集計ステージ
  • $project
  • $match
  • $limit
  • $skip
  • $unwind
  • $group
  • $sort
  • $lookup
  • サポートされていない集計ステージ
  • サポートされているメソッド

このガイドでは、MongoDB .NET/C# ドライバーで LINQ を使用する方法を説明します。LINQ では、言語キーワードと演算子を使用して、厳密に型指定されたオブジェクト コレクションを対象にクエリを作成できます。.NET/C# ドライバーは、LINQ クエリを自動的に集計操作に変換します。

このガイドの例では、Atlas サンプル データセットで提供されている sample_restaurants データベースの restaurants コレクションを使用します。無料の MongoDB Atlas クラスターを作成し、サンプル データセットをロードする方法については、 クイック スタートを参照してください。

次の RestaurantAddress、およびGradeEntry クラスは、このコレクション内のドキュメントをモデル化します。

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() メソッドは、IQueryable 拡張メソッドと MongoDB 固有のメソッドのセットを持つ IMongoQueryable インスタンスを返します。

クエリ可能なオブジェクトを取得したら、メソッド構文を使用してクエリを作成できます。一部のパイプライン ステージでは、SQL クエリ構文に似たクエリ理解構文もサポートされています。

LINQ を使用してクエリを作成する方法を確認するには、Method Syntax または Query Syntax タブを選択します。

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" } }

Tip

クエリ結果へのアクセス

ToList() または ToCursor() メソッドを使用してクエリの結果にアクセスすることもできます。

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

LINQ を使用して集計パイプラインを作成できます。 .NET/C# ドライバーは、各 LINQ ステートメントを対応する集計パイプライン ステージに自動的に変換します。 このセクションでは、どの 集計パイプライン ステージ がサポートされているかを学習できます。

集計パイプライン ステージの詳細については、サーバー マニュアルの「集計ステージ」ページを参照してください。

$project 集計ステージでは、指定されたフィールドのみを含むドキュメントが返されます。

LINQ を使用して $project ステージを生成する方法を確認するには、 Method Syntax または Query Syntax タブを選択します。

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 集計ステージでは、指定された条件に一致するドキュメントが返されます。

LINQ を使用して $match ステージを生成する方法を確認するには、 Method Syntax または Query Syntax タブを選択します。

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);

上記の例では、条件に一致する最初の 2 つのレストランをスキップし、残りを返します。結果には、次のドキュメントが含まれています。

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

$unwind 集計ステージでは、指定された配列フィールドを分解し、その配列内の各要素のドキュメントを返します。

LINQ を使用して $unwind ステージを生成する方法を確認するには、Method Syntax または Query Syntax タブを選択します。

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 集計ステージでは、指定した基準に従ってドキュメントをグループに分割します。

LINQ を使用して $group ステージを生成する方法を確認するには、Method Syntax または Query Syntax タブを選択します。

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 集計ステージでは、指定した順序でクエリの結果が返されます。

LINQ を使用して $sort ステージを生成する方法を確認するには、Method Syntax または Query Syntax タブを選択します。

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 フィールドでアルファベット順に並べ替えられ、RestaurantId フィールドで 2 次降順で並べ替えられたクエリ結果が返されます。以下は返された結果に含まれるドキュメントのサブセットです。

// 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 集計ステージでは、1 つのコレクションのドキュメントを同じデータベース内の別のコレクションのドキュメントに結合します。$lookup ステージでは、各入力ドキュメントに新しい配列フィールドが追加されます。新しい配列フィールドには、結合済みコレクションと一致するドキュメントが含まれます。

注意

ルックアップを実行するには、AsQueryable メソッドを使用して両方のコレクションをクエリ可能にする必要があります。

コレクションをクエリ可能にする方法については、「 コレクションをクエリ可能にする 」を参照してください。

sample_restaurants データベース内のレストランのレビューを含む reviews という 2 番目のコレクションについて考えてみましょう。$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; }
}

LINQ を使用して $lookup ステージを生成する方法を確認するには、 Method Syntax または Query Syntax タブを選択します。

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" }
]
}

MongoDB .NET/C# ドライバーの LINQ 実装では、次の集計ステージはサポートされていません。

  • $redact

  • $geoNear

  • $out

以下は、MongoDB .NET/C# ドライバーの LINQ 実装でサポートされているメソッドの一部です。

メソッド名
説明
Any
指定された条件に一致するドキュメントがあるかどうかを判定します
Average
指定されたフィールドの平均を計算します
Count
指定された条件に一致するドキュメントの数を表す Int32 を返します。
LongCount
指定された条件に一致するドキュメントの数を表す Int64 を返します。
Distinct
指定された条件に一致する個別のドキュメントを返します
First
最初に一致するドキュメントを返し、見つからない場合は例外をスローします。
FirstOrDefault
最初に一致するドキュメントを返します。見つからない場合は null を返します。
GroupBy
指定した条件に基づいてドキュメントをグループ化します
GroupJoin
同じデータベース内の別のコレクションへの左外部結合を実行します
Max
指定された最大値を持つドキュメントを返します
OfType
指定した型に一致するドキュメントを返します
OrderBy, OrderByDescending
指定されたソート順序で結果を返します
ThenBy, ThenByDescending
二次ソートを指定できるようにします
Select
指定された基準に基づいてドキュメントを選択します
SelectMany
シーケンスの各要素を投影し、結果のシーケンスを 1 つのドキュメントに結合します。
Single
一致するドキュメントのみを返し、ドキュメントが1つだけない場合は例外をスローします
SingleOrDefault
一致するドキュメントを 1 つ返すか、一致するドキュメントがない場合は null を返します。
Skip
指定された数の文書をスキップし、残りの結果を返します
Sum
指定されたフィールドの値の合計を返します
Take
返される結果の数を指定します
Where
指定した条件に一致するすべてのドキュメントを返します

戻る

集計