Docs 菜单
Docs 主页
/ / /
C#/.NET
/

Atlas Search

在此页面上

  • 概述
  • 创建 Atlas Search 索引
  • Atlas Search 操作符
  • 自动完成(Autocomplete)
  • 多个子句
  • EmbeddedDocument
  • Equals
  • Exists
  • GeoShape
  • GeoWithin
  • 更多类似内容
  • Near
  • 短语
  • QueryString
  • 范围
  • 正则表达式(Regex)
  • span
  • 文本(Text)
  • 通配符

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

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

注意

仅适用于 Atlas for MongoDB v4.2 及更高版本

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

本指南中的示例使用名为 guitars 的集合中的以下文档:

{ "_id": 1, "make": "Fender", "description": "Classic guitars known for their versatility.", "establishedYear": 1946, "in_stock": true, "rating": 9 }
{ "_id": 2, "make": "Gibson", "description": "Classic guitars known for their rich, full tones.", "establishedYear": 1902, "in_stock": true, "rating": 8 }
{ "_id": 3, "make": "PRS", "description": "High-end guitars known for their quality.", "establishedYear": 1985, "in_stock": true, "rating": 9 }
{ "_id": 4, "make": "Kiesel", "description": "Quality guitars made only for custom orders.", "establishedYear": 2015, "in_stock": false }
{ "_id": 5, "make": "Ibanez", "description": "Well-crafted guitars used by many professional guitarists.", "establishedYear": 1957, "in_stock": true, "rating": 7 }
{ "_id": 6, "make": "Strandberg", "description": "Modern guitars known for their headless models.", "establishedYear": 1982, "in_stock": false }

以下 Guitar 类对此集合中的文档进行建模。

public class Guitar
{
public int Id { get; set; }
public string Make { get; set; }
public List<string> Models { get; set; }
public int EstablishedYear { get; set; }
[BsonElement("in_stock")]
public bool InStock { get; set; }
public int? Rating { get; set; }
}

注意

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

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

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

要了解如何创建 Atlas Search 索引,请参阅创建 Atlas Search 索引Atlas 指南。

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

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

以下示例使用 make 字段中的字符串“Gib”在 guitars 集合中执行自动补全搜索。

var result = guitarsCollection.Aggregate()
.Search(Builders<Guitar>.Search.Autocomplete(g => g.Make, "Gib"), indexName: "guitarmakes")
.ToList();

注意

如果您要搜索的字段已由搜索索引建立索引,则必须将索引名称传递给Autocomplete调用。如果搜索索引不存在,则使用默认索引。

此搜索将返回如下文档:

{ "_id" : 2, "make" : "Gibson", "description" : "Classic guitars known for their rich, full tones.", "establishedYear" : 1902, "in_stock" : true, "rating" : 8 }

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

使用 Compound() 方法将两个或更多操作符组合到单次搜索中。

以下示例在 guitars 集合中搜索符合以下所有条件的任何文档:

  • 文档上存在 rating 字段

  • in_stock 字段不是 false

  • establishedYear 字段的值大于 1940

var result = guitarsCollection.Aggregate()
.Search(Builders<Guitar>.Search.Compound()
.Must(Builders<Guitar>.Search.Exists(g => g.Rating))
.MustNot(Builders<Guitar>.Search.Equals(g => g.InStock, false))
.Must(Builders<Guitar>.Search.Range(g => g.EstablishedYear, SearchRangeBuilder.Gt(1940))))
.ToList();

搜索会返回以下文档:

{ "_id" : 1, "make" : "Fender", "description" : "...", "establishedYear" : 1946, "in_stock" : true, "rating" : 9 }
{ "_id" : 3, "make" : "PRS", "description" : "...", "establishedYear" : 1985, "in_stock" : true, "rating" : 9 }
{ "_id" : 5, "make" : "Ibanez", "description" : "...", "establishedYear" : 1957, "in_stock" : true, "rating" : 7 }

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

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

注意

要搜索嵌入式文档,您必须在数组字段上创建embeddedDocument索引。

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

考虑到guitars集合中的某些文档已添加productDetails字段,用于保存产品详细信息对象的数组:

{ "_id": 1, "make": "Fender", "description": "...", "establishedYear": 1946, "in_stock": true, "rating": 9, "productDetails": [{"product_id": 1234, "serial": "YZ5678"}] }
{ "_id": 2, "make": "Gibson", "description": "...", "establishedYear": 1902, "in_stock": true, "rating": 8 }
{ "_id": 3, "make": "PRS", "description": "...", "establishedYear": 1985, "in_stock": true, "rating": 9, "productDetails": [{"product_id": 9870, "serial": "AB5555"}] }
{ "_id": 4, "make": "Kiesel", "description": "...", "establishedYear": 2015, "in_stock": false }
{ "_id": 5, "make": "Ibanez", "description": "...", "establishedYear": 1957, "in_stock": true, "rating": 7, "productDetails": [{"product_id": 5432, "serial": "ZZ1234"}] }
{ "_id": 6, "make": "Strandberg", "description": "...", "establishedYear": 1982, "in_stock": false }

productDetails字段上创建embeddedDocument索引后,您可以对该字段中的文档执行 Atlas 搜索操作。以下示例对productDetails数组字段执行文本搜索,并返回serial字段值为"YZ5678"的所有文档:

var result = guitarsCollection.Aggregate()
.Search(Builders<Guitar>.Search.EmbeddedDocument(
g => g.ProductDetails,
Builders<ProductDetails>.Search.Text(p => p.Serial, "YZ5678")
)).ToList();
return result;

此搜索将返回如下文档:

{ "_id" : 1, "make" : "Fender", "description" : "Classic guitars known for their versatility.", "establishedYear" : 1946, "in_stock" : true, "rating" : 9, "productDetails" : [{ "product_id" : 1234, "serial" : "YZ5678" }] }

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

使用 Equals() 方法检查字段是否与指定值匹配。

如下示例会在 guitars 集合中搜索 in_stock(有存货)字段值为 true 的任何文档。

var result = guitarsCollection.Aggregate()
.Search(Builders<Guitar>.Search.Equals(g => g.InStock, true))
.ToList();

搜索会返回以下文档:

{ "_id" : 1, "make" : "Fender", "description" : "...", "establishedYear" : 1946, "in_stock" : true, "rating" : 9 }
{ "_id" : 2, "make" : "Gibson", "description" : "...", "establishedYear" : 1902, "in_stock" : true, "rating" : 8 }
{ "_id" : 3, "make" : "PRS", "description" : "...", "establishedYear" : 1985, "in_stock" : true, "rating" : 9 }
{ "_id" : 5, "make" : "Ibanez", "description" : "...", "establishedYear" : 1957, "in_stock" : true, "rating" : 7 }

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

使用 Exists() 方法搜索其中存在指定索引字段名称的文档。如果指定的字段存在但没有为期创建索引,此文档不会包含在结果集内。

如下示例会在 guitars 集合中搜索存在 rating 字段的任何文档。

var result = guitarsCollection.Aggregate()
.Search(Builders<Guitar>.Search.Exists(g => g.Rating))
.ToList();

搜索会返回以下文档:

{ "_id" : 1, "make" : "Fender", "description" : "...", "establishedYear" : 1946, "in_stock" : true, "rating" : 9 }
{ "_id" : 2, "make" : "Gibson", "description" : "...", "establishedYear" : 1902, "in_stock" : true, "rating" : 8 }
{ "_id" : 3, "make" : "PRS", "description" : "...", "establishedYear" : 1985, "in_stock" : true, "rating" : 9 }
{ "_id" : 5, "make" : "Ibanez", "description" : "...", "establishedYear" : 1957, "in_stock" : true, "rating" : 7 }

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

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

注意

Atlas Search 不支持以下内容:

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

  • 平面 XY 坐标系(二维)

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

考虑到 guitars 集合中的某些文档已添加 in_stock_location 字段。现在,集合中的变更文档如下所示:

{ "_id": 1, "make": "Fender", "description": "...", "establishedYear": 1946, "in_stock": true, "in_stock_location": { "type": "Point", "coordinates": [ -73.93615, 40.69791 ]}, "rating": 9 }
{ "_id": 2, "make": "Gibson", "description": "...", "establishedYear": 1902, "in_stock": true, "in_stock_location": { "type": "Point", "coordinates": [ 47.6062, 122.321 ]}, "rating": 8 }

以下示例搜索 in_stock_location 字段中的坐标与指定多边形相交的所有文档:

GeoJsonPolygon<GeoJson2DGeographicCoordinates> searchArea = new(new(new(new GeoJson2DGeographicCoordinates[]
{
new(-72.93615, 41.69791),
new(-72.93615, 40.59791),
new(-74.93615, 40.59791),
new(-74.93615, 41.69791),
new(-72.93615, 41.69791),
})));
var result = guitarsCollection.Aggregate()
.Search(Builders<Guitar>.Search.GeoShape(g => g.InStockLocation, GeoShapeRelation.Intersects, searchArea))
.ToList();

此搜索将返回如下文档:

{ "_id" : 1, "make" : "Fender", "description" : "...", "establishedYear" : 1946, "in_stock" : true, "in_stock_location" : { "type" : "Point", "coordinates" : ["-73.93615", "40.69791"] }, "rating" : 9 }

要了解有关geoShape操作符的详情,请参阅geoShape Atlas 指南。

使用GeoWithin()方法搜索文档,其中指定的GeoJSON字段的坐标位于给定几何图形内。您可以搜索以下范围内的点:

  • 圆形

  • 边界框

  • 多边形

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

注意

Atlas Search 不支持以下内容:

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

  • 平面 XY 坐标系(二维)

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

考虑到 guitars 集合中的某些文档已添加 in_stock_location 字段。现在,集合中的变更文档如下所示:

{ "_id": 1, "make": "Fender", "description": "...", "establishedYear": 1946, "in_stock": true, "in_stock_location": { "type": "Point", "coordinates": [ -73.93615, 40.69791 ]}, "rating": 9 }
{ "_id": 2, "make": "Gibson", "description": "...", "establishedYear": 1902, "in_stock": true, "in_stock_location": { "type": "Point", "coordinates": [ 47.6062, 122.321 ]}, "rating": 8 }

以下示例会搜索 in_stock_location 字段中的坐标位于指定多边形内的所有文档:

GeoJsonPolygon<GeoJson2DGeographicCoordinates> searchArea = new(new(new(new GeoJson2DGeographicCoordinates[]
{
new(-74.3994140625, 40.5305017757),
new(-74.7290039063, 40.5805846641),
new(-74.7729492188, 40.9467136651),
new(-74.0698242188, 41.1290213475),
new(-73.65234375, 40.9964840144),
new(-72.6416015625, 40.9467136651),
new(-72.3559570313, 40.7971774152),
new(-74.3994140625, 40.5305017757),
})));
var result = guitarsCollection.Aggregate()
.Search(Builders<Guitar>.Search.GeoWithin(g => g.InStockLocation, searchArea))
.ToList();

此搜索将返回如下文档:

{ "_id" : 1, "make" : "Fender", "description" : "Classic guitars known for their versatility.", "establishedYear" : 1946, "in_stock" : true, "in_stock_location" : { "type" : "Point", "coordinates" : ["-73.93615", "40.69791"] }, "rating" : 9 }

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

使用 MoreLikeThis() 方法搜索与输入文档类似的文档。

以下示例会在 guitars 集合中搜索与 Description 字段值为“high quality”的对象相似的文档。

var searchDocument = new GuitarSearch()
{
Description = "high quality",
};
var result = guitarsCollection.Aggregate()
.Search(Builders<Guitar>.Search.MoreLikeThis(searchDocument))
.ToList();

搜索会返回以下文档:

{ "_id" : 3, "make" : "PRS", "description" : "High-end guitars known for their quality.", "establishedYear" : 1985, "in_stock" : true, "rating" : 9 }
{ "_id" : 4, "make" : "Kiesel", "description" : "Quality guitars made only for custom orders.", "establishedYear" : 2015, "in_stock" : false, "rating" : null }

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

使用 Near() 方法搜索指定的字段接近给定值的文档。您可以对以下对象执行搜索:

  • 数字字段

  • 日期字段

  • 地理点

以下示例会在 guitars 集合中搜索 rating 字段的值接近 9 的文档。根据该值与数字 9 的接近程度按顺序返回文档。

var result = guitarsCollection.Aggregate()
.Search(Builders<Guitar>.Search.Near(g => g.Rating, 9, 1))
.ToList();

搜索会返回以下文档:

{ "_id" : 1, "make" : "Fender", "description" : "...", "establishedYear" : 1946, "in_stock" : true, "rating" : 9 }
{ "_id" : 3, "make" : "PRS", "description" : "...", "establishedYear" : 1985, "in_stock" : true, "rating" : 9 }
{ "_id" : 2, "make" : "Gibson", "description" : "...", "establishedYear" : 1902, "in_stock" : true, "rating" : 8 }
{ "_id" : 5, "make" : "Ibanez", "description" : "...", "establishedYear" : 1957, "in_stock" : true, "rating" : 7 }

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

使用 Phrase() 方法搜索指定字段包含输入字符串的文档。

如下示例将在 guitars 集合中搜索 description(说明)字段包含短语“classic guitars”的文档。

var result = guitarsCollection.Aggregate()
.Search(Builders<Guitar>.Search.Phrase(g => g.Description, "classic guitars"))
.ToList();

搜索会返回以下文档:

{ "_id" : 1, "make" : "Fender", "description" : "Classic guitars known for their versatility.", "establishedYear" : 1946, "in_stock" : true, "rating" : 9 }
{ "_id" : 2, "make" : "Gibson", "description" : "Classic guitars known for their rich, full tones.", "establishedYear" : 1902, "in_stock" : true, "rating" : 8 }

您还可以按以下方式搜索与多个单独短语匹配的文档:

var result = guitarsCollection.Aggregate()
.Search(Builders<Guitar>.Search.Phrase(g => g.Description, new List<string>() { "classic guitars", "quality guitars" }))
.ToList();

此搜索将返回以下文档:

{ "_id" : 1, "make" : "Fender", "description" : "Classic guitars known for their versatility.", "establishedYear" : 1946, "in_stock" : true, "rating" : 9 }
{ "_id" : 4, "make" : "Kiesel", "description" : "Quality guitars made only for custom orders.", "establishedYear" : 2015, "in_stock" : false, "rating" : null }
{ "_id" : 2, "make" : "Gibson", "description" : "Classic guitars known for their rich, full tones.", "establishedYear" : 1902, "in_stock" : true, "rating" : 8 }

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

使用 QueryString() 方法,将一个字符串与以下操作符和分隔符结合使用以搜索文档:

  • AND

  • OR

  • NOT

  • ()

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

  • 包含字符串“classic”字符串“quality”

  • 不包含字符串“自定义”

var result = guitarsCollection.Aggregate()
.Search(Builders<Guitar>.Search.QueryString(g => g.Description, "(classic OR quality) AND NOT custom"))
.ToList();

搜索会返回以下文档:

{ "_id" : 1, "make" : "Fender", "description" : "Classic guitars known for their versatility.", "establishedYear" : 1946, "in_stock" : true, "rating" : 9 }
{ "_id" : 3, "make" : "PRS", "description" : "High-end guitars known for their quality.", "establishedYear" : 1985, "in_stock" : true, "rating" : 9 }
{ "_id" : 2, "make" : "Gibson", "description" : "Classic guitars known for their rich, full tones.", "establishedYear" : 1902, "in_stock" : true, "rating" : 8 }

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

使用 Range() 方法搜索指定字段的值处于给定数字或日期范围内的文档。

以下示例会在 guitars 集合中搜索 establishedYear 值大于 1980 且小于 2020 的所有文档。

var result = guitarsCollection.Aggregate()
.Search(Builders<Guitar>.Search.Range(g => g.EstablishedYear, SearchRangeBuilder.Gt(1980).Lt(2020)))
.ToList();

此搜索将返回以下结果:

{ "_id" : 3, "make" : "PRS", "description" : "High-end guitars known for their quality.", "establishedYear" : 1985, "in_stock" : true, "rating" : 9 }
{ "_id" : 4, "make" : "Kiesel", "description" : "Quality guitars made only for custom orders.", "establishedYear" : 2015, "in_stock" : false, "rating" : null }
{ "_id" : 6, "make" : "Strandberg", "description" : "Modern guitars known for their headless models.", "establishedYear" : 1982, "in_stock" : false, "rating" : null }

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

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

以下示例会在 guitars 集合中搜索 make 字段的值恰好包含六个字母的文档。

var regex = "[A-Za-z]{6}";
var result = guitarsCollection.Aggregate()
.Search(Builders<Guitar>.Search.Regex(g => g.Make, regex))
.ToList();

此搜索将返回以下结果:

{ "_id" : 1, "make" : "Fender", "description" : "Classic guitars known for their versatility.", "establishedYear" : 1946, "in_stock" : true, "rating" : 9 }
{ "_id" : 2, "make" : "Gibson", "description" : "Classic guitars known for their rich, full tones.", "establishedYear" : 1902, "in_stock" : true, "rating" : 8 }
{ "_id" : 4, "make" : "Kiesel", "description" : "Quality guitars made only for custom orders.", "establishedYear" : 2015, "in_stock" : false, "rating" : null }
{ "_id" : 5, "make" : "Ibanez", "description" : "Well-crafted guitars used by many professional guitarists.", "establishedYear" : 1957, "in_stock" : true, "rating" : 7 }

注意

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

var result = guitarsCollection.Aggregate()
.Search(Builders<Guitar>.Search.Regex(g => g.Make, regex, true))
.ToList();

allowAnalyzedField选项设置为 true 可能会导致意外的搜索结果。要了解详情,请参阅正则表达式行为。

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

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

注意

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

如下示例将在 guitars 集合中搜索 description(说明)字段的值包含彼此相邻的字符串“guitars”和“quality”的文档。

var searchTerms = new[]
{
Builders<Guitar>.SearchSpan.Term(g => g.Description, "guitars"),
Builders<Guitar>.SearchSpan.Term(g => g.Description, "quality")
};
var result = guitarsCollection.Aggregate()
.Search(Builders<Guitar>.Search.Span(Builders<Guitar>.SearchSpan.Near(searchTerms, 1)))
.ToList();

此搜索将返回如下文档:

{ "_id" : 4, "make" : "Kiesel", "description" : "Quality guitars made only for custom orders.", "establishedYear" : 2015, "in_stock" : false, "rating" : null }

虽然带有 _id: 3 的文档包含字符串“guitars”和“quality”,但它们由多个单词分隔,搜索结果忽略了该文档。

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

使用 Text() 方法在文档中搜索给定的字符串或字符串数组。如果给定的字符串中有多个词,Atlas Search 还会分别为字符串中的每个词查找匹配项。

以下示例会在 guitars 集合中搜索 description 字段的值包含字符串“used by professionals”(专业人员使用)的文档。

var result = guitarsCollection.Aggregate()
.Search(Builders<Guitar>.Search.Text(g => g.Description, "used by professional"))
.ToList();

此搜索将返回如下文档:

{ "_id" : 5, "make" : "Ibanez", "description" : "Well-crafted guitars used by many professional guitarists.", "establishedYear" : 1957, "in_stock" : true, "rating" : 7 }

提示

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

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

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

字符
说明
?
匹配任意单个字符。
*
匹配 0 个或更多字符。
\
转义字符

以下示例会搜索 make 字段的值包含字符串“Strand”,后跟任何其他字符的文档。

var result = guitarsCollection.Aggregate()
.Search(Builders<Guitar>.Search.Wildcard(g => g.Make, "Strand*"))
.ToList();

此搜索将返回如下文档:

{ "_id" : 6, "make" : "Strandberg", "description" : "Modern guitars known for their headless models.", "establishedYear" : 1982, "in_stock" : false, "rating" : null }

注意

默认情况下,wildcard 操作符不能在分析字段上运行。您可以通过将 allowAnalyzedField 选项设置为 true,支持在分析字段上执行该操作符,如下所示:

var result = guitarsCollection.Aggregate()
.Search(Builders<Guitar>.Search.Wildcard(g => g.Make, "Strand*", true))
.ToList();

allowAnalyzedField选项设置为 true 可能会导致意外的搜索结果。要了解详情,请参阅通配符行为。

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

← 与构建者合作