Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
Click here >
Docs 菜单
Docs 主页
/ /

MongoDB Search

在本指南中,您可以了解如何使用 Search 生成器,通过 MongoDB .NET/C# 驱动程序构建一个聚合管道阶段。

要了解有关 $search 管道阶段的更多信息,请参阅 $search。

注意

Atlas和 Community Edition 版本要求

$search 聚合管道操作符仅适用于在运行 MongoDB v4.2 或更高版本的MongoDB Atlas集群上托管的集合,或者运行 MongoDB v8.2 或更高版本的MongoDB Community Edition集群上托管的集合。集合必须包含在MongoDB 搜索索引中。要了解有关此操作符所需设置和功能的更多信息,请参阅MongoDB 搜索文档。

本指南中的示例使用 sample_mflix数据库中的 movies集合。此集合中的文档包含有关电影的信息,包括标题、情节、类型和评级。以下 Movie 类对此集合中的文档进行建模:

[BsonIgnoreExtraElements]
public class Movie
{
[BsonId]
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!;
[BsonElement("plot_embedding")]
public float[] PlotEmbedding { get; set; } = null!;
public double Score { get; set; }
[BsonElement("paginationToken")]
public string PaginationToken { get; set; } = null!;
}

Movie 类引用以下 Imdb 类,该类对每个文档中的嵌套 imdb字段进行建模:

[BsonIgnoreExtraElements]
public class Imdb
{
public double Rating { get; set; }
public int Votes { get; set; }
public int Id { get; set; }
}

注意

示例数据中的驼峰命名字段名称

movies 集合中的文档使用驼峰命名约定。本指南中的示例使用 ConventionPack 将集合中的字段反序列化为 Pascal 语句,然后映射到 Movie 类中的属性。

如需了解有关自定义序列化的更多信息,请参阅自定义序列化

本指南中的一些示例使用了相关章节中介绍的其他集合和模型类。 所有集合均来自Atlas提供的示例数据集。请参阅.NET/ C#驱动程序入门,学习;了解如何创建免费的MongoDB 集群并加载此示例数据。

注意

示例数据中不一致的字段类型

movies集合中的某些文档将 imdb.ratingimdb.votes 字段存储为字符串而不是数字。如果您在模型类中将这些字段定义为 doubleint,则驱动程序在反序列化这些文档时会抛出 FormatException

要处理具有混合字段类型的文档,实现接受多个BSON 类型的自定义序列化器,并将其与 [BsonSerializer] 属性一起应用受影响的属性:

[BsonIgnoreExtraElements]
public class Imdb
{
[BsonSerializer(typeof(FlexibleDoubleSerializer))]
public double Rating { get; set; }
[BsonSerializer(typeof(FlexibleInt32Serializer))]
public int Votes { get; set; }
public int Id { get; set; }
}

要学习;了解如何实现FlexibleDoubleSerializer 等自定义序列化器,请参阅自定义序列化器。

在对Atlas集合执行搜索之前,必须先在该集合上创建MongoDB 搜索索引。MongoDB搜索索引是一种以可搜索格式对数据进行分类的数据结构。

要学习;了解如何创建MongoDB搜索索引,请参阅创建MongoDB搜索索引指南。

Search 类包含可用于执行 $search 操作的方法。有关可用 $search 操作符和收集器的完整列表,请参阅Atlas操作符和收集器指南

使用 Autocomplete() 方法,搜索包含不完整输入字符串中的字符序列的单词或短语。

以下示例对 title字段执行自动完成查询,查找以 string "Gravity" 开头的文本:

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 操作符的更多信息,请参阅 autocomplete Atlas 指南。

注意

自动完成查询的索引

您必须创建支持自动完成的MongoDB搜索索引,才能成功执行自动完成查询。要学习更多信息,请参阅Atlas文档中的如何对字段进行索引以支持自动完成

创建MongoDB Search索引后,必须将索引名称传递给 Autocomplete() 方法,如前面的示例所示。

使用 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 操作符的更多信息,请参阅 compound Atlas 指南。

使用 EmbeddedDocument() 方法对字段的数组值中的文档执行搜索操作。

注意

需要嵌入式文档索引

要对嵌入式文档进行Atlas Search ,您必须在数组字段上创建 embeddedDocument 索引。

要了解如何定义 embeddedDocument 索引,请参阅 Atlas 文档中的为 embeddedDocument 类型定义索引

此示例使用 sample_restaurants数据库中的 restaurants集合。以下类对该集合中的文档进行建模:

[BsonIgnoreExtraElements]
public class Restaurant
{
[BsonId]
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!;
}
[BsonIgnoreExtraElements]
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() 方法检查字段是否与指定值匹配。

以下示例在 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 操作符的更多信息,请参阅 equals Atlas 指南。

使用 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 操作符的更多信息,请参阅exists Atlas 指南。

使用 Facet() 方法按指定分面字段中的值或范围对结果进行分组,并返回每个组的计数。

您可以将 Facet() 方法同时用于 $search$searchMeta 阶段。MongoDB建议使用带有 $searchMeta 阶段的分面(Facet)来检索仅针对查询 的元数据结果。要使用 $search 阶段检索元数据结果和查询结果,必须使用 $$SEARCH_META聚合变量。要学习;了解有关此变量的更多信息,请参阅 SEARCH_META 聚合变量 Atlas指南。

适用以下限制:

  • 只能对单个字段运行分面查询。无法对字段群组运行分面查询。

  • 只能在运行 MongoDB v6.0 的集群上对分片集合运行分面查询。

以下示例在 movies集合中搜索 year字段的值大于或等于 2000 的任何文档。该查询使用 Facet() 方法进程输入文档,根据 genres字段在结果中返回的最大数量 100分面(Facet)面类别。此查询返回找到的不同类型类别的数量:

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() 方法搜索与给定的几何图形相关的文档。当指定要搜索的坐标时,必须首先指定经度,然后指定纬度。经度值可以介于 -180180(含)之间。纬度值可以介于 -9090(含)之间。

注意

MongoDB Search 不支持以下内容:

  • 非默认坐标参考系 (CRS)

  • 平面 XY 坐标系(二维)

  • 坐标对 点符号 (pointFieldName: [12, 34])

此示例使用 sample_mflix数据库中的 theaters集合。以下类对该集合中的文档进行建模:

[BsonIgnoreExtraElements]
public class Theater
{
[BsonId]
public ObjectId Id { get; set; }
public int TheaterId { get; set; }
public TheaterLocation Location { get; set; } = null!;
}
[BsonIgnoreExtraElements]
public class TheaterLocation
{
[BsonElement("geo")]
public GeoJsonPoint<GeoJson2DGeographicCoordinates> Geo { get; set; } = null!;
}

以下示例会在该集合中搜索 location.geo字段中的坐标与明尼苏达州明尼阿波利斯地区的指定多边形相交的所有文档:

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() 方法搜索指定 GeoJSON 字段坐标在给定几何范围内的文档。您可以搜索以下范围内的点:

  • 圆形

  • 边界框

  • 多边形

指定要搜索的坐标时,必须首先指定经度,然后指定纬度。经度值可以介于 -180180 (含)之间。纬度值可以介于 -9090(含)之间。

注意

MongoDB Search 不支持以下内容:

  • 非默认坐标参考系 (CRS)

  • 平面 XY 坐标系(二维)

  • 坐标对 点符号 (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() 方法搜索与输入文档类似的文档。

此示例使用以下类来指定用于搜索的输入文档:

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 操作符的更多信息,请参阅 moreLikeThis Atlas 指南。

使用 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 操作符的更多信息,请参阅 near Atlas 指南。

使用 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() 方法,将一个字符串与以下操作符和分隔符结合使用以搜索文档:

  • AND

  • OR

  • NOT

  • ()

以下示例会在 movies 集合中搜索 plot 字段的值与以下每个条件匹配的文档:

  • 包含字符串 "time" 字符串 "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 操作符的更多信息,请参阅 queryString Atlas 指南。

使用 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" : "..." } }
...

要搜索指定字段的值在某一字符串范围内的文档,必须首先在该字段上创建词索引。创建索引后,您可以根据范围字符串搜索文档。以下示例返回 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 操作符的更多信息,请参阅 range Atlas 指南。

使用 Regex() 方法使用正则表达式搜索文档。

以下示例在 movies集合中搜索 title字段的值恰好包含六个字母的文档:

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

默认下,regex操作符不能在分析字段上运行。您可以通过将 allowAnalyzedField 选项设置为 true,允许其在分析字段上运行,如下所示:

var result = moviesCollection.Aggregate()
.Search(Builders<Movie>.Search.Regex(m => m.Title, regex,
allowAnalyzedField: true))
.ToList();

allowAnalyzedField 选项设置为 true 可能会导致意外的搜索结果。要学习;了解详情,请参阅行为Atlas regex指南中的。

要了解有关 regex 操作符的更多信息,请参阅 regex Atlas 指南。

使用 Span() 方法,搜索字段区域内的文本搜索匹配项。您可以使用该方法,按照指定的精度查找相似的字符串。

注意

Span 操作符性能

span 操作符比其他操作符的计算量更大,因为查询必须跟踪位置信息。

以下示例在 movies集合中搜索 plot字段的值包含字符串 "time""travel" 且彼此相邻的单词的文档:

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 操作员的更多信息,请参阅 span Atlas 指南。

使用 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" : "..." } }
...

提示

多术语搜索行为

如果您的搜索字符串包含多个术语,此方法还会分别查找字符串中的每个术语的匹配项。

要了解有关 text 操作符的更多信息,请参阅 text Atlas 指南。

使用 Wildcard() 方法在搜索字符串中使用可以匹配任何字符的特殊字符来搜索文档。您可以在搜索中使用以下字符:

字符
说明

?

匹配任意单个字符。

*

匹配 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 行为

要了解有关 wildcard 操作符的更多信息,请参阅 wildcard Atlas 指南。

您可以使用 SearchPathDefinitionBuilder 类指定要搜索的字段或多个字段的路径。使用 Builders<TDocument>.SearchPath访问权限SearchPathDefinitionBuilder实例并调用其方法之一以指定搜索路径。以下部分介绍了可用的方法。

提示

搜索路径

要学习;了解有关搜索路径的更多信息,请参阅Atlas文档中的构造查询路径

使用 Single() 方法指定一个字段作为搜索路径。以下示例展示了指定字段的三种方法:在类型化模型中使用 Lambda表达式、传递 string 字段名称,例如其值在运行时已知的 fieldName 变量或方法参数,或者使用非类型化文档。

注意

您传递给 Single() 方法的字段必须包含在搜索索引定义中。如果未包含该字段, MongoDB Server将返回空结果设立,而不返回错误。

当您使用类型化模型并且在编译时知道字段名称时,请使用 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" : "..." } },
"..."
]

当您使用类型化模型但在编译时不知道字段名称时,请使用 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 对象而不是类型化模型时,还必须将字段名称指定为字符串。

以下示例在无类型集合中搜索 plot字段中包含文本 "secret agent" 的文档:

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() 方法指定多个字段的搜索路径。结果设立包括与任何指定字段匹配的文档。

注意

您必须在搜索索引定义中包含传递给 Multi() 方法的所有字段。如果您传递未包含的字段, MongoDB Server会默默地将其排除在搜索之外。

以下示例在 plottitle字段中搜索短语 "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" },
"..."
]

分析器通过应用小写等操作将文本进程为可搜索的词元。MongoDB Server在索引字段时应用分析器,并在对该字段运行查询时再次应用分析器。如果在创建搜索索引时指定multi选项, MongoDB Server还会存储由备用分析器生成的第二设立词元。

您可以使用 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" },
"..."
]

提示

分析器

要学习;了解有关分析器的更多信息,请参阅分析器Atlas文档中的。

使用 Wildcard() 方法指定使用通配符匹配字段名称的搜索路径。您可以在字段名称中使用 * 字符来匹配任意字符序列。

MongoDB Server仅搜索满足以下条件的字段:

  • 该字段必须已建立索引。

  • 字段名称必须与指定模式匹配。

  • 字段的数据类型必须与搜索操作符匹配。示例,Text()查询仅搜索字符串字段。

以下示例在名称以 "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" : "..." } },
"..."
]

注意

通配符性能

广泛模式(例如 "*")匹配所有索引字段,可能会影响大型索引的查询性能。

要学习;了解有关通配符路径的更多信息,请参阅Atlas文档中的构造查询路径

MongoDB Server会为其从MongoDB搜索查询中返回的每个文档分配一个相关性分数。查询按从最高分到最低分的顺序返回文档。要学习;了解有关如何分配分数的更多信息,请参阅分数Atlas指南。

分配给返回文档的分数是文档元数据的一部分。您可以通过在聚合管道中使用 $project 阶段,将每个返回文档的分数与结果设立一起包含在内。

以下示例在 movies集合中搜索 title字段的值恰好包含六个字母的文档,并使用 $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 }
...

您可以通过传递 SearchOptions对象作为参数来修改 Search() 方法的行为。

SearchOptions 类包含以下属性:

属性
说明

CountOptions

The options for counting the search results.
Default: null

Highlight

The options for displaying search terms in their original context.
Default: null

IndexName

The index to use for the search.
Data type: string
Default: null

ReturnStoredSource

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: boolean
Default: false

ScoreDetails

A flag that specifies whether to return detailed information about the score for each document in the results.
Data type: boolean
Default: false

SearchAfter

The starting point for pagination. When set, the search retrieves documents starting immediately after the specified reference point.
Data type: string
Default: null

SearchBefore

The end point for pagination. When set, the search retrieves documents starting immediately before the specified reference point.
Data type: string
Default: null

Sort

The sorting criteria to apply to the results.
Default: null

Tracking

The options for tracking search terms.
Default: null

以下示例通过执行以下操作对MongoDB搜索操作的结果进行分页:

  • 定义使用 MetaSearchSequenceToken() 构建器方法的投影,该方法指定一个 PaginationToken 来包含参考点

  • 创建 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" : "..." } }
...

提示

分页文档

要学习;了解有关MongoDB Search 分页的更多信息,请参阅Atlas文档中的对结果进行分页

后退

运行数据库命令

在此页面上