Overview
このガイドでは、 Searchビルダーを使用して MongoDB .NET/C# ドライバーで$search集計パイプライン ステージを構築する方法を学びます。
$searchパイプライン ステージの詳細については、 $search を参照してください。
注意
Atlas および Community Edition のバージョン要件
$search 集計パイプライン演算子は、 MongoDB v4.2 以降を実行中MongoDB Atlasクラスター、またはMongoDB v8.2 以降を実行中MongoDB Community Editionクラスターでホストされているコレクションでのみ使用できます。コレクションはMongoDB 検索インデックスでカバーされている必要があります。必要な設定とこの演算子の機能の詳細については、MongoDB 検索するのドキュメントを参照してください。
サンプル データ
このガイドの例では、 sample_mflixデータベースの moviesコレクションを使用します。このコレクションのドキュメントには、タイトル、プロット、ジャンル、評価など、映画に関する情報が含まれています。次の Movieクラスは、このコレクション内のドキュメントをモデル化します。
[] public class Movie { [] public ObjectId Id { get; set; } public string Title { get; set; } = null!; public string Plot { get; set; } = null!; public string[] Genres { get; set; } = null!; public int Year { get; set; } public string Rated { get; set; } = null!; public Imdb Imdb { get; set; } = null!; [] public float[] PlotEmbedding { get; set; } = null!; public double Score { get; set; } [] public string PaginationToken { get; set; } = null!; }
Movieクラスは次の Imdbクラスを参照します。このクラスは、各ドキュメント内のネストされた imdbフィールドをモデル化します。
[] public class Imdb { public double Rating { get; set; } public int Votes { get; set; } public int Id { get; set; } }
注意
サンプル データ内のキャメルケースのフィールド名
movies コレクションのドキュメントは、キャメル ケースの命名規則を使用します。このガイドの例では、ConventionPack を使用してコレクション内のフィールドをパスカル ケースに逆シリアル化し、Movie クラスのプロパティにマップします。
カスタム直列化について詳しくは、「 カスタム直列化 」を参照してください。
このガイドの一部の例では、関連するセクションで紹介されている追加のコレクションとモデル クラスを使用します。 すべてのコレクションは、Atlas が提供するサンプルデータセットから取得されています。MongoDBクラスターを無料で作成して、このサンプルデータをロードする方法については、 .NET/ C#ドライバーを使い始める を参照してください。
注意
サンプル データで一貫性のないフィールド型
moviesコレクション内の一部のドキュメントでは、imdb.rating フィールドと imdb.votes フィールドが数値ではなく文字列として保存されています。モデルクラスでこれらのフィールドを double または int として定義すると、ドライバーはそれらのドキュメントを逆直列化するときに FormatException をスローします。
混合フィールド型のドキュメントを処理するには、複数のBSON型を受け入れるカスタム シリアライザーを実装し、影響を受けるプロパティに [BsonSerializer] 属性を使用して適用します。
[] public class Imdb { [] public double Rating { get; set; } [] public int Votes { get; set; } public int Id { get; set; } }
FlexibleDoubleSerializer などのカスタム シリアライザーを実装する方法については、カスタム シリアライザー を参照してください。
MongoDB Search インデックスの作成
Atlasコレクションで検索を実行する前に、まずコレクションに検索インデックスを作成する必要があります。MongoDB 検索インデックスは、検索可能な形式でデータを分類するデータ構造です。
MongoDB 検索インデックスの作成方法については、MongoDB 検索インデックスの作成ガイドを参照してください。
MongoDB 検索する 演算子とコレクター
Searchクラスには、$search 操作を実行するために使用できるメソッドが含まれています。使用可能な $search 演算子とコレクターの完全なリストについては、Atlas の演算子とコレクターに関するガイドを参照してください。
オートコンプリート
Autocomplete()メソッドを使用して、不完全な入力 string からの文字シーケンスを含む単語またはフレーズを検索します。
次の例では、string "Gravity" で始まるテキストの titleフィールドに対してオートコンプリート クエリを実行します。
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Autocomplete(m => m.Title, "Gravity"), indexName: "movietitles") .ToList();
... { "_id" : ObjectId("..."), "title" : "Gravity", "plot" : "...", "genres" : ["Drama", "Sci-Fi", "Thriller"], "year" : 2013, "rated" : "PG-13", "imdb" : { "rating" : 7.7, "votes" : "...", "id" : "..." } } ...
autocomplete演算子の詳細については、Atlas のオートコンプリートガイドを参照してください。
注意
オートコンプリート クエリ用インデックス
オートコンプリート クエリを正常に実行するには、オートコンプリートをサポートするMongoDB 検索インデックスを作成する必要があります。詳細を学ぶには、Atlas ドキュメントのオートコンプリート用にフィールドをインデックスする方法を参照してください。
MongoDB Searchインデックスを作成したら、前述の例に示すように、インデックス名を Autocomplete() メソッドに渡す必要があります。
複合
2 つ以上の演算子を 1 つの検索に結合するには、 Compound()メソッドを使用します。
次の例では、movies コレクション内で次のすべての条件に一致するドキュメントを検索します。
imdb.ratingフィールドはドキュメントに存在するratedフィールド値は"G"ではありませんyearフィールドの値が 2000 より大きい
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Compound() .Must(Builders<Movie>.Search.Exists(m => m.Imdb.Rating)) .MustNot(Builders<Movie>.Search.Equals(m => m.Rated, "G")) .Must(Builders<Movie>.Search.Range(m => m.Year, SearchRangeBuilder.Gt(2000)))) .ToList();
... { "_id" : ObjectId("..."), "title" : "The Dark Knight", "plot" : "...", "genres" : ["Action", "Crime", "Drama"], "year" : 2008, "rated" : "PG-13", "imdb" : { "rating" : 9.0, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "Inception", "plot" : "...", "genres" : ["Action", "Adventure", "Sci-Fi"], "year" : 2010, "rated" : "PG-13", "imdb" : { "rating" : 8.8, "votes" : "...", "id" : "..." } } ...
compound演算子の詳細については、 Atlas複合ガイド をご覧ください。
embeddedDocument
EmbeddedDocument()メソッドを使用して、フィールドの配列値内のドキュメントに対して検索操作を実行します。
注意
必須の埋め込みドキュメントインデックス
埋め込みドキュメントを検索するには、配列フィールドにembeddedDocumentインデックスを作成する必要があります。
embeddedDocumentインデックスを定義する方法については、Atlas ドキュメントの「 embeddedDocument 型のインデックスの定義」を参照してください。
この例では、sample_restaurantsデータベースの restaurantsコレクションを使用します。次の クラスは、そのコレクション内のドキュメントをモデル化します。
[] public class Restaurant { [] public ObjectId Id { get; set; } public string Name { get; set; } = null!; public string Cuisine { get; set; } = null!; public string Borough { get; set; } = null!; public List<GradeEntry> Grades { get; set; } = null!; }
[] public class GradeEntry { public string Grade { get; set; } = null!; public int? Score { get; set; } }
次の例では、そのコレクションで、grades 配列に grade フィールドの値が "A" であるエントリが含まれているレストランを検索します。
var result = restaurantsCollection.Aggregate() .Search(Builders<Restaurant>.Search.EmbeddedDocument( r => r.Grades, Builders<GradeEntry>.Search.Equals(g => g.Grade, "A") ), indexName: "restaurantsembedded").ToList();
... { "_id" : ObjectId("..."), "name" : "Riviera Caterer", "cuisine" : "American", "borough" : "Brooklyn", "grades" : [{ "grade" : "A", "score" : 5 }, { "grade" : "B", "score" : 23 }] } ...
embeddedDocument演算子の詳細については、 embeddedDocument Atlas のガイドを参照してください。
equals
フィールドが指定された値と一致するかどうかを確認するには、 Equals()メソッドを使用します。
次の例では、 moviesコレクションで、yearフィールドの値が 2000 であるドキュメントを検索します。
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Equals(m => m.Year, 2000)) .ToList();
... { "_id" : ObjectId("..."), "title" : "Gladiator", "plot" : "...", "genres" : ["Action", "Adventure", "Drama"], "year" : 2000, "rated" : "R", "imdb" : { "rating" : 8.5, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "Cast Away", "plot" : "...", "genres" : ["Adventure", "Drama", "Romance"], "year" : 2000, "rated" : "PG-13", "imdb" : { "rating" : 7.8, "votes" : "...", "id" : "..." } } ...
equals演算子の詳細については、 Atlas ガイドと等価を参照してください。
exists
指定されたインデックス付きフィールド名が存在するドキュメントを検索するには、Exists() メソッドを使用します。指定されたフィールドが存在してもインデックスが作成されていない場合、ドキュメントは結果セットに含まれません。
次の例では、moviesコレクションで imdb.ratingフィールドが存在するドキュメントを検索します。検索では、imdb.ratingフィールドが存在するすべてのドキュメントが返されます。
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Exists(m => m.Imdb.Rating)) .ToList();
... { "_id" : ObjectId("..."), "title" : "The Godfather", "plot" : "...", "genres" : ["Crime", "Drama"], "year" : 1972, "rated" : "R", "imdb" : { "rating" : 9.2, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "The Shawshank Redemption", "plot" : "...", "genres" : ["Drama"], "year" : 1994, "rated" : "R", "imdb" : { "rating" : 9.3, "votes" : "...", "id" : "..." } } ...
exists演算子の詳細については、既存のAtlasガイドを参照してください。
Facet
Facet() メソッドを使用して、指定されたファセットフィールドの値または範囲で結果をグループ化し、各グループのカウントを返します。
Facet() メソッドは、$search ステージと $searchMeta ステージの両方で使用できます。MongoDB、クエリのみのメタデータ結果を検索するために、 $searchMeta ステージでファセットを使用することを推奨しています。$search ステージを使用してメタデータ結果とクエリ結果を検索するには、$$SEARCH_META集計変数を使用する必要があります。この変数の詳細については、SEARCH_META 集計変数 Atlasガイド を参照してください。
次の制限が適用されます。
ファセット クエリは単一のフィールドに対してのみ実行できます。フィールドのグループに対してファセット クエリを実行することはできません。
MongoDB v6.0 を実行しているクラスター上のシャーディングされたコレクションに対してのみファセット クエリを実行できます。
次の例では、moviesコレクションで、yearフィールドの値が 2000 以上のドキュメントを検索します。クエリは Facet() メソッドを使用して入力ドキュメントを処理します。genresフィールドに基づいて結果に返す最大数の 100ファセットカテゴリが含まれます。クエリは、見つかった個別のジャンルの数を返します。
var result = moviesCollection.Aggregate() .SearchMeta( Builders<Movie>.Search.Facet( Builders<Movie>.Search.Range(m => m.Year, SearchRangeBuilder.Gte(2000)), Builders<Movie>.SearchFacet.String("genres", m => m.Genres, 100)), indexName: "moviesfacetsearch") .Single() .Facet["genres"].Buckets.Count();
23
facetコレクターの詳細については、「ファセットAtlas ガイド」を参照してください。
geoShape
GeoShape()メソッドを使用して、特定のジオメトリに関連するドキュメントを検索します。 検索する座標を指定する場合は、最初に 経度 、次に 緯度 を指定する必要があります。 経度の値は、両端を含む-180から180までです。 緯度の値は、両端を含む-90から90までです。
注意
MongoDB Search は以下の機能をサポートしていません。
非デフォルトの座標参照システム(CRS)
平面 XY 座標系 (2 次元)
座標ペアのポイント表記(pointFieldName: [12, 34])
この例では、sample_mflixデータベースの theatersコレクションを使用します。次の クラスは、そのコレクション内のドキュメントをモデル化します。
[] public class Theater { [] public ObjectId Id { get; set; } public int TheaterId { get; set; } public TheaterLocation Location { get; set; } = null!; }
[] public class TheaterLocation { [] public GeoJsonPoint<GeoJson2DGeographicCoordinates> Geo { get; set; } = null!; }
次の例では、そのコレクションで、location.geoフィールドの座標が最小値 MN 領域内の指定された多角形と交差されているすべてのドキュメントを検索します。
GeoJsonPolygon<GeoJson2DGeographicCoordinates> searchArea = new(new(new(new GeoJson2DGeographicCoordinates[] { new(-93.5, 44.7), new(-93.5, 45.0), new(-93.0, 45.0), new(-93.0, 44.7), new(-93.5, 44.7), }))); var result = theatersCollection.Aggregate() .Search(Builders<Theater>.Search.GeoShape( t => t.Location.Geo, GeoShapeRelation.Intersects, searchArea), indexName: "theatersgeo") .ToList();
... { "_id" : ObjectId("..."), "theaterId" : 1000, "location" : { "geo" : { "type" : "Point", "coordinates" : [-93.24565, 44.85466] } } } ...
geoShape演算子の詳細については、 geoShape Atlas ガイドを参照してください。
geoWithin
GeoWithin()メソッドを使用して、指定されたGeoJSONフィールドの座標が特定のジオメトリ内にあるドキュメントを検索します。 内にあるポイントを検索できます。
円
境界ボックス
多角形
検索する座標を指定する場合は、最初に 経度 、次に 緯度 を指定する必要があります。 経度の値は、両端を含む-180から180までです。 緯度の値は、両端を含む-90から90までです。
注意
MongoDB Search は以下の機能をサポートしていません。
非デフォルトの座標参照システム(CRS)
平面 XY 座標系 (2 次元)
座標ペアのポイント表記(pointFieldName: [12, 34])
次の例では、 theatersコレクションで、location.geoフィールドの座標が指定された多角形内にあるすべてのドキュメントを検索します。
GeoJsonPolygon<GeoJson2DGeographicCoordinates> searchArea = new(new(new(new GeoJson2DGeographicCoordinates[] { new(-94.0, 44.5), new(-94.0, 45.2), new(-92.5, 45.2), new(-92.5, 44.5), new(-94.0, 44.5), }))); var result = theatersCollection.Aggregate() .Search(Builders<Theater>.Search.GeoWithin(t => t.Location.Geo, searchArea), indexName: "theatersgeo") .ToList();
... { "_id" : ObjectId("..."), "theaterId" : 1000, "location" : { "geo" : { "type" : "Point", "coordinates" : [-93.24565, 44.85466] } } } ...
geoWithin演算子の詳細については、 geoWithin Atlas ガイド を参照してください。
で
指定値のリストと一致するフィールド値を持つドキュメントを検索するには、In() メソッドを使用します。
次の例では、 moviesコレクションで、"Action" または "Comedy" のいずれかを含む genres 配列を持つドキュメントを検索します。
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.In(m => m.Genres, new[] { "Action", "Comedy" })) .ToList();
... { "_id" : ObjectId("..."), "title" : "Home Alone", "plot" : "...", "genres" : ["Comedy", "Family"], "year" : 1990, "rated" : "PG", "imdb" : { "rating" : 7.4, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "Die Hard", "plot" : "...", "genres" : ["Action", "Thriller"], "year" : 1988, "rated" : "R", "imdb" : { "rating" : 8.2, "votes" : "...", "id" : "..." } } ...
moreLikeThis
入力ドキュメントに類似するドキュメントを検索するには、 MoreLikeThis()メソッドを使用します。
この例では、次のクラスを使用して、検索の入力ドキュメントを指定します。
public class MovieSearch { public string Plot { get; set; } = null!; }
次の例では、 moviesコレクションで、plotフィールドの値が "time travel" であるオブジェクトに類似するドキュメントを検索します。
var searchDocument = new MovieSearch() { Plot = "time travel", }; var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.MoreLikeThis(searchDocument)) .ToList();
... { "_id" : ObjectId("..."), "title" : "Thrill Seekers", "plot" : "...", "genres" : ["Action", "Sci-Fi", "Thriller"], "year" : 1999, "rated" : "...", "imdb" : { "rating" : "...", "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "About Time", "plot" : "...", "genres" : ["Drama", "Fantasy", "Romance"], "year" : 2013, "rated" : "R", "imdb" : { "rating" : 7.8, "votes" : "...", "id" : "..." } } ...
moreLikeThis演算子の詳細については、Atlas ガイドのmoreLikeThis Atlas ガイドを参照してください。
near
Near()メソッドを使用して、指定したフィールドが指定の値に近いドキュメントを検索します。 検索は、次に対して実行できます。
数値フィールド
日付フィールド
地理的ポイント
次の例では、 moviesコレクションで、imdb.ratingフィールドの値が 8.5 に近いドキュメントを検索します。値が 8.5 に近いかどうかに基づいて、ドキュメントは順番に返されます。
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Near(m => m.Imdb.Rating, 8.5, 1)) .ToList();
... { "_id" : ObjectId("..."), "title" : "The Dark Knight", "plot" : "...", "genres" : ["Action", "Crime", "Drama"], "year" : 2008, "rated" : "PG-13", "imdb" : { "rating" : 9.0, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "The Godfather", "plot" : "...", "genres" : ["Crime", "Drama"], "year" : 1972, "rated" : "R", "imdb" : { "rating" : 9.2, "votes" : "...", "id" : "..." } } ...
near演算子の詳細については、近くのAtlas ガイドを参照してください。
phrase
指定したフィールドに入力stringが含まれているドキュメントを検索するには、Phrase() メソッドを使用します。
次の例では、 moviesコレクションで、plotフィールドにフレーズ "time travel" が含まれているドキュメントを検索します。
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Phrase(m => m.Plot, "time travel")) .ToList();
... { "_id" : ObjectId("..."), "title" : "The Time Traveler's Wife", "plot" : "...", "genres" : ["Drama", "Fantasy", "Romance"], "year" : 2009, "rated" : "PG-13", "imdb" : { "rating" : 7.1, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "Safety Not Guaranteed", "plot" : "...", "genres" : ["Comedy", "Drama", "Romance"], "year" : 2012, "rated" : "R", "imdb" : { "rating" : 7, "votes" : "...", "id" : "..." } } ...
また、コレクション内で plotフィールドで "time travel" または "space adventure" のいずれかを含むドキュメントを検索することもできます。
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Phrase(m => m.Plot, new List<string>() { "time travel", "space adventure" })) .ToList();
... { "_id" : ObjectId("..."), "title" : "The Time Traveler's Wife", "plot" : "...", "genres" : ["Drama", "Fantasy", "Romance"], "year" : 2009, "rated" : "PG-13", "imdb" : { "rating" : 7.1, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "Safety Not Guaranteed", "plot" : "...", "genres" : ["Comedy", "Drama", "Romance"], "year" : 2012, "rated" : "R", "imdb" : { "rating" : 7, "votes" : "...", "id" : "..." } } ...
phrase演算子について詳しくは、Atlas ガイドのフレーズを参照してください。
queryString
QueryString()メソッドを使用して、次の演算子と区切り文字を含む string を使用してドキュメントを検索します。
ANDORNOT()
次の例では、 moviesコレクションで、 plotフィールドの値が次の各条件に一致するドキュメントを検索します。
string
"time"または string"space"が含まれますstring を含みません
"comedy"
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.QueryString(m => m.Plot, "(time OR space) AND NOT comedy")) .ToList();
... { "_id" : ObjectId("..."), "title" : "Interstellar", "plot" : "...", "genres" : ["Adventure", "Drama", "Sci-Fi"], "year" : 2014, "rated" : "PG-13", "imdb" : { "rating" : 8.7, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "Tomorrowland", "plot" : "...", "genres" : ["Action", "Adventure", "Family"], "year" : 2015, "rated" : "PG", "imdb" : { "rating" : 6.6, "votes" : "...", "id" : "..." } } ...
queryString演算子の詳細については、 Atlas ガイドのqueryStringを参照してください。
Range(範囲)
Range() メソッドを使用して、指定フィールドの値が特定の数値、日付、または文字列の範囲内にあるドキュメントを検索します。
次の例では、 moviesコレクションで、year の値が 2000 より大きく 2010 より小さいすべてのドキュメントを検索します。
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search .Range(m => m.Year, SearchRangeBuilder.Gt(2000).Lt(2010))) .ToList();
... { "_id" : ObjectId("..."), "title" : "The Dark Knight", "plot" : "...", "genres" : ["Action", "Crime", "Drama"], "year" : 2008, "rated" : "PG-13", "imdb" : { "rating" : 9.0, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "The Departed", "plot" : "...", "genres" : ["Crime", "Drama", "Thriller"], "year" : 2006, "rated" : "R", "imdb" : { "rating" : 8.5, "votes" : "...", "id" : "..." } } ...
指定したフィールドの値が string の範囲内にあるドキュメントを検索するには、まずフィールドに トークンインデックス を作成する必要があります。インデックスを作成 したら、string の範囲に基づいてドキュメントを検索できます。次の例では、titleフィールドの値が "A" と "G" の間にあるドキュメントを辞書順に比較して返します。
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search .Range(m => m.Title, SearchRangeV2Builder.Gte("A").Lte("G"))) .ToList();
... { "_id" : ObjectId("..."), "title" : "Apollo 13", "plot" : "...", "genres" : ["Adventure", "Drama", "History"], "year" : 1995, "rated" : "PG", "imdb" : { "rating" : 7.6, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "Braveheart", "plot" : "...", "genres" : ["Biography", "Drama", "History"], "year" : 1995, "rated" : "R", "imdb" : { "rating" : 8.3, "votes" : "...", "id" : "..." } } ...
range演算子の詳細については、 Atlas の範囲ガイド を参照してください。
regex
正規表現を使用してドキュメントを検索するには、 Regex()メソッドを使用します。
次の例では、 moviesコレクションで、titleフィールドの値に 6 文字だけが含まれているドキュメントを検索します。
var regex = "[A-Za-z]{6}"; var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Regex(m => m.Title, regex, allowAnalyzedField: true)) .ToList();
... { "_id" : ObjectId("..."), "title" : "Gandhi", "plot" : "...", "genres" : ["Biography", "Drama", "History"], "year" : 1982, "rated" : "PG", "imdb" : { "rating" : 8.0, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "Batman", "plot" : "...", "genres" : ["Action", "Adventure"], "year" : 1989, "rated" : "PG-13", "imdb" : { "rating" : 7.5, "votes" : "...", "id" : "..." } } ...
注意
分析されたフィールドでの正規表現の実行
デフォルトでは 、regex 演算子は 分析対象フィールドでは実行できません。次のように、allowAnalyzedField オプションを true に設定することで、分析するフィールドで実行することができます。
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Regex(m => m.Title, regex, allowAnalyzedField: true)) .ToList();
allowAnalyzedField オプションを true に設定すると、予期しない検索結果が発生する可能性があります。詳しくは、 Atlas regexガイドの 「動作」 を参照してください。
regex演算子の詳細については、 Atlas ガイドの正規表現を参照してください。
span
フィールドのリージョン内に一致するテキスト検索を検索するには、 Span()メソッドを使用します。 このメソッドを使用すると、指定した精度で相互に近い文字列を検索できます。
注意
Span 演算子のパフォーマンス
span演算子は、クエリが位置情報を追跡する必要があるため、他の演算子よりも計算負荷が高くなります。
次の例では、moviesコレクションで、plotフィールドの値に"time"と"travel"が互いに1単語以内に含まれるドキュメントを検索します。
var searchTerms = new[] { Builders<Movie>.SearchSpan.Term(m => m.Plot, "time"), Builders<Movie>.SearchSpan.Term(m => m.Plot, "travel") }; var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Span(Builders<Movie>.SearchSpan.Near(searchTerms, 1))) .ToList();
... { "_id" : ObjectId("..."), "title" : "The Time Traveler's Wife", "plot" : "...", "genres" : ["Drama", "Fantasy", "Romance"], "year" : 2009, "rated" : "PG-13", "imdb" : { "rating" : 7.1, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "About Time", "plot" : "...", "genres" : ["Drama", "Fantasy", "Romance"], "year" : 2013, "rated" : "R", "imdb" : { "rating" : 7.8, "votes" : "...", "id" : "..." } } ...
span演算子の詳細については、 Atlas ガイドの範囲を参照してください。
Text
ドキュメント内で指定された string または string の配列を検索するには、Text() メソッドを使用します。特定の string に複数の検索期間がある場合、 MongoDB Search は 文字列内の各期間の一致も個別に検索します
次の例では、 moviesコレクションで、plotフィールドの値に string "secret agent" が含まれるドキュメントを検索します。
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Text(m => m.Plot, "secret agent")) .ToList();
... { "_id" : ObjectId("..."), "title" : "Spy Kids", "plot" : "...", "genres" : ["Action", "Adventure", "Comedy"], "year" : 2001, "rated" : "PG", "imdb" : { "rating" : 5.4, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "The Spy Who Loved Me", "plot" : "...", "genres" : ["Action", "Adventure", "Thriller"], "year" : 1977, "rated" : "PG", "imdb" : { "rating" : 7.1, "votes" : "...", "id" : "..." } } ...
Tip
マルチターム検索の動作
検索 string に複数のタームが含まれている場合、このメソッドは string 内の各タームの一致も個別に検索します
text演算子の詳細については、Atlas ガイドのテキストを参照してください。
ワイルドカード
Wildcard() メソッドを使用して、検索stringに任意の文字に一致する特殊文字を使用してドキュメントを検索します。 検索では、次の文字を使用できます。
文字 | 説明 |
|---|---|
| 任意の 1 文字と一致 |
| 0 文字以上の文字と一致 |
| エスケープ文字 |
次の例では、 titleフィールドの値に string "Amer" とそれに続く他の文字が含まれているドキュメントを検索します。
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Wildcard(m => m.Title, "Amer*", allowAnalyzedField: true)) .ToList();
... { "_id" : ObjectId("..."), "title" : "American Beauty", "plot" : "...", "genres" : ["Drama"], "year" : 1999, "rated" : "R", "imdb" : { "rating" : 8.4, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "American Gangster", "plot" : "...", "genres" : ["Biography", "Crime", "Drama"], "year" : 2007, "rated" : "R", "imdb" : { "rating" : 7.8, "votes" : "...", "id" : "..." } } ...
注意
分析対象フィールドでのワイルドカードの実行
デフォルトでは 、wildcard 演算子は 分析対象フィールドでは実行できません。次のように、allowAnalyzedField オプションを true に設定することで、分析フィールドで実行できるようになります。
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Wildcard(m => m.Title, "Amer*", allowAnalyzedField: true)) .ToList();
allowAnalyzedFieldオプションを true に設定すると、予期しない検索結果が発生する可能性があります。 詳しくは、「ワイルドカードの動作 」を参照してください。
wildcard演算子の詳細については、ワイルドカードAtlas のガイドを参照してください。
検索パスの指定
検索するフィールドへのパスは、SearchPathDefinitionBuilderクラスを使用して指定できます。 Builders<TDocument>.SearchPath を使用して SearchPathDefinitionBuilderインスタンスにアクセスし、そのメソッドの 1 つを呼び出して検索パスを指定します。次のセクションでは、利用可能なメソッドについて説明します。
シングル フィールド
検索パスとして 1 つのフィールドを指定するには、Single() メソッドを使用します。次の例は、フィールドを指定する 3 つの方法です。型指定されたモデルでラムダ式を使用する、実行時に値が既知であるfieldName変数やメソッド パラメータなどの文字列フィールド名を渡します、または型指定されていないドキュメントを使用します。
注意
Lambda式
型付きモデルを操作していて、コンパイル時にフィールド名がわかっている場合は、 ラムダ式を使用します。この形式では、コンパイル時に型をチェックできます。
次の例では、 plotフィールドでテキスト "secret agent" を含むドキュメントを検索します。
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Text( Builders<Movie>.SearchPath.Single(m => m.Plot), "secret agent")) .ToList();
[ "...", { "_id" : ObjectId("..."), "title" : "Spy Kids", "plot" : "...", "genres" : ["Action", "Adventure", "Comedy"], "year" : 2001, "rated" : "PG", "imdb" : { "rating" : 5.4, "votes" : "...", "id" : "..." } }, "...", { "_id" : ObjectId("..."), "title" : "The Spy Who Loved Me", "plot" : "...", "genres" : ["Action", "Adventure", "Thriller"], "year" : 1977, "rated" : "PG", "imdb" : { "rating" : 7.1, "votes" : "...", "id" : "..." } }, "..." ]
string フィールド名
型付きモデルを操作しているが、コンパイル時にフィールド名が不明な場合は、FieldDefinition<TDocument> を使用します。ユーザー入力または構成ファイルからフィールド名を検索する場合は、この形式の使用を検討してください。
次の例ではフィールド名を FieldDefinition<Movie> 変数に割り当て、それを Single() に渡します。
FieldDefinition<Movie> runtimeField = fieldName; var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Text( Builders<Movie>.SearchPath.Single(runtimeField), "secret agent")) .ToList();
[ "...", { "_id" : ObjectId("..."), "title" : "Spy Kids", "plot" : "...", "genres" : ["Action", "Adventure", "Comedy"], "year" : 2001, "rated" : "PG", "imdb" : { "rating" : 5.4, "votes" : "...", "id" : "..." } }, "...", { "_id" : ObjectId("..."), "title" : "The Spy Who Loved Me", "plot" : "...", "genres" : ["Action", "Adventure", "Thriller"], "year" : 1977, "rated" : "PG", "imdb" : { "rating" : 7.1, "votes" : "...", "id" : "..." } }, "..." ]
BsonDocument
型指定されたモデルではなく BsonDocument オブジェクトを操作する場合は、フィールド名を string として指定する必要があります。
次の例では、型なしのコレクションで、テキスト "secret agent" を含むドキュメントを plotフィールドで検索します。
var result = moviesCollectionBson.Aggregate() .Search(Builders<BsonDocument>.Search.Text( Builders<BsonDocument>.SearchPath.Single("plot"), "secret agent")) .ToList();
[ "...", { "_id" : ObjectId("..."), "title" : "Spy Kids", "plot" : "...", "...": "..." }, "...", { "_id" : ObjectId("..."), "title" : "The Spy Who Loved Me", "plot" : "...", "...": "..." }, "..." ]
複数のフィールド
複数のフィールドの検索パスを指定するには、Multi() メソッドを使用します。結果セットには、指定されたフィールドのいずれかに一致するドキュメントが含まれます。
注意
次の例では、plot または titleフィールドのいずれかでフレーズ "time travel" を検索します。
var result = moviesCollection.Aggregate().Search( Builders<Movie>.Search.Phrase(Builders<Movie>.SearchPath .Multi(m => m.Plot, m => m.Title), "time travel"), indexName: "moviesmulti") .ToList();
[ "...", { "title" : "Safety Not Guaranteed", "year" : 2012, "rated" : "R" }, { "title" : "The Time Traveler's Wife", "year" : 2009, "rated" : "PG-13" }, "..." ]
analyzer
アナライザは、小文字化などの操作を適用して、テキストを検索可能なトークンに処理します。 MongoDB Server は、フィールドのインデックスを作成するときにアナライザを適用し、そのフィールドに対してクエリを実行中ときに再度アナライザを適用します。検索インデックスを作成するときに マルチ オプションを指定すると、 MongoDB Server は代替アナライザによって生成された 2 つ目のトークン セットも保存します。
Analyzer() メソッドを使用すると、フィールドのデフォルトのアナライザによって生成されたトークンではなく、multiアナライザによって生成されたトークンに対してクエリを実行できます。 Analyzer() に渡す名前は、基礎となるアナライザの名前ではなく、インデックス定義内の multi ブロックのキー名である必要があります。
次の例では、"lucene" という名前の multiアナライザを使用して、titleフィールドでテキスト "gravity" を含むドキュメントを検索しています。
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Text( Builders<Movie>.SearchPath.Analyzer(m => m.Title, "lucene"), "gravity"), indexName: "moviesanalyzer") .ToList();
[ "...", { "title" : "Gravity", "year" : 2013, "rated" : "PG-13" }, "..." ]
ワイルドカード パス
フィールド名を一致させるためにワイルドカード文字を使用する検索パスを指定するには、Wildcard() メソッドを使用します。フィールド名の * 文字を使用して、任意の文字シーケンスを一致させることができます。
MongoDB Server は、次の条件を満たすフィールドのみを検索します。
フィールドはインデックスを付ける必要があります。
フィールド名は指定されたパターンと一致する必要があります。
フィールドのデータ型は検索演算子と一致する必要があります。例、
Text()クエリは string フィールドのみを検索します。
次の例では、名前が "p" で始まるすべてのフィールドで、"secret agent" というテキストを含むドキュメントを検索します。
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Text( Builders<Movie>.SearchPath.Wildcard("p*"), "secret agent")) .ToList();
[ "...", { "_id" : ObjectId("..."), "title" : "Spy Kids", "plot" : "...", "genres" : ["Action", "Adventure", "Comedy"], "year" : 2001, "rated" : "PG", "imdb" : { "rating" : 5.4, "votes" : "...", "id" : "..." } }, "...", { "_id" : ObjectId("..."), "title" : "The Spy Who Loved Me", "plot" : "...", "genres" : ["Action", "Adventure", "Thriller"], "year" : 1977, "rated" : "PG", "imdb" : { "rating" : 7.1, "votes" : "...", "id" : "..." } }, "..." ]
注意
ワイルドカード パフォーマンス
"*" などの幅広いパターンはすべてのインデックス付きフィールドに一致するため、大規模なインデックスではクエリ パフォーマンスに影響を与える可能性があります。
スコアのドキュメント
MongoDB Server は、 MongoDB Search クエリから返されるすべてのドキュメントに関連性スコアを割り当てます。クエリは、最高スコアから最低スコアの順にドキュメントを返します。スコアが割り当てられる方法の詳細については、「スコア Atlasガイド」を参照してください。
返されたドキュメントに割り当てられるスコアは、ドキュメントのメタデータの一部です。集計パイプラインで $project ステージを使用すると、返された各ドキュメントのスコアを結果セットに含めることができます。
次の例では、 moviesコレクションで、titleフィールドの値に 6 文字だけが含まれているドキュメントを検索し、$project ステージを使用して返されるドキュメントに score という名前のフィールドを追加します。
var regex = "[A-Za-z]{6}"; var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Regex(m => m.Title, regex, allowAnalyzedField: true), indexName: "moviescore") .Project<Movie>(Builders<Movie>.Projection .Include(m => m.Id) .Include(m => m.Title) .Include(m => m.Plot) .MetaSearchScore(m => m.Score)) .ToList();
... { "_id" : ObjectId("..."), "title" : "Gandhi", "plot" : "...", "score" : 1.0 } { "_id" : ObjectId("..."), "title" : "Batman", "plot" : "...", "score" : 1.0 } ...
MongoDB 検索するの動作を変更する
SearchOptionsオブジェクトをパラメーターとして渡すことで、Search() メソッドの動作を変更できます。
SearchOptionsクラスには、次のプロパティが含まれています。
プロパティ | 説明 |
|---|---|
| The options for counting the search results. Data type: SearchCountOptions Default: null |
| The options for displaying search terms in their original context. Data type: SearchHighlightOptions<TDocument> Default: null |
| The index to use for the search. Data type: stringDefault: null |
| A flag that specifies whether to perform a full document lookup on
the database or to return only stored source fields directly from
MongoDB Search. Data type: booleanDefault: false |
| A flag that specifies whether to return detailed information about the
score for each document in the results. Data type: booleanDefault: false |
| The starting point for pagination. When set, the search retrieves documents
starting immediately after the specified reference point. Data type: stringDefault: null |
| The end point for pagination. When set, the search retrieves documents
starting immediately before the specified reference point. Data type: stringDefault: null |
| The sorting criteria to apply to the results. Data type: SortDefinition<TDocument> Default: null |
| The options for tracking search terms. Data type: SearchTrackingOptions Default: null |
SearchAfter の例
次の例では、次のアクションを実行してMongoDB検索する操作の結果をページ分割します。
MetaSearchSequenceToken()ビルダ メソッドを使用するプロジェクションを定義します。このメソッドでは、基準点を含むPaginationTokenを指定しますSearchOptionsインデックスとソート条件を設定する SearchOptions インスタンスを作成します。初期検索を実行して、
plotフィールド値に"time travel"というテキストを含むドキュメントを見つけ、プロジェクションとオプションを操作に適用します。同じ
SearchOptionsインスタンスのSearchAfterプロパティを設定し、基本検索の最初の結果の後に次の検索を開始するように指示します。同じ一致条件を持つ別の検索操作を実行し、検索オプションを適用して結果をページネーションします
var projection = Builders<Movie>.Projection .Include(x => x.Title) .MetaSearchSequenceToken(x => x.PaginationToken); var searchDefinition = Builders<Movie>.Search.Text(m => m.Plot, "time travel"); var searchOptions = new SearchOptions<Movie> { IndexName = "default", Sort = Builders<Movie>.Sort.Ascending(m => m.Id) }; // Runs the base search operation var baseSearchResults = moviesCollection.Aggregate() .Search(searchDefinition, searchOptions) .Project<Movie>(projection) .ToList(); if (baseSearchResults.Count == 0) return baseSearchResults; // Sets the starting point for the next search searchOptions.SearchAfter = baseSearchResults[0].PaginationToken; var result = moviesCollection.Aggregate() .Search(searchDefinition, searchOptions) .Project<Movie>(projection) .ToList();
... { "_id" : ObjectId("..."), "title" : "About Time", "plot" : "...", "genres" : ["Comedy", "Drama", "Romance"], "year" : 2013, "rated" : "R", "imdb" : { "rating" : 7.8, "votes" : "...", "id" : "..." } } ...