与构建者合作
Overview
在本指南中,您可以学习 .NET/C# Driver 提供的助手类或构建器,用于创建操作中使用的类型。使用构建器有助于在编译时识别错误并在运行时避免错误。本指南接受可用于以下任务的构建器类:
创建筛选器定义
创建投影
定义排序顺序
定义更新操作
选择索引键
提示
MongoDB C# Analyzer
MongoDB C# Analyzer 是一个工具,可帮助您分析构建者定义并了解.NET/ C#代码如何转换为MongoDB查询API。 有关更多信息和安装说明,请参阅MongoDB C# Analyzer 参考页面。
如果想进一步了解如何使用构建器构建定义和语法,请阅读本指南。
样本类
本指南中的代码示例演示了如何使用构建器来创建类型,以便与样本集合 plants.flowers
中的文档进行交互。。此集合中的文档由以下 Flower
类进行建模:
public class Flower { public ObjectId Id { get; set; } public string Name { get; set; } public string Category { get; set; } public double Price { get; set; } public List<string> Season { get; set; } public double Stock { get; set; } public string Description { get; set; } }
每个构建者类都采用通用类型参数TDocument
,表示您正在使用的文档的类型。在本指南中,Flower
类是每个构建者类示例中使用的文档类型。
构造筛选器
FilterDefinitionBuilder
类提供用于生成查询的类型安全接口。假设您要查询集合中是否存在符合以下条件的文档:
Price
字段值小于 20Category
字段值为“Perennial”
使用构建者创建具有类型化变体的筛选器定义:
var builder = Builders<Flower>.Filter; var filter = builder.Lt(f => f.Price, 20) & builder.Eq(f => f.Category, "Perennial");
使用类型变体形式可以保证编译时安全性。此外,您的 IDE 可以提供重构支持。
或者,可使用基于字符串的字段名称来构造筛选器:
var builder = Builders<Flower>.Filter; var filter = builder.Lt("Price", 20) & builder.Eq("Category", "Perennial");
数组操作符
如果您的文档具有已序列化为数组的属性或字段,则可使用以 Any
开头的方法(例如 AnyEq()
或 AnyLt()
)将整个数组与单个项目进行比较。
使用构建器检查集合中的哪些文档具有包含“winter”的 Season
数组:
var builder = Builders<Flower>.Filter; var filter = builder.AnyEq(f => f.Season, "winter");
创建投影
ProjectionDefinitionBuilder
类提供用于定义投影的类型安全接口。假设您想对 Name
和 Price
字段创建一个投影,但不包括 Id
字段。
使用构建器创建具有类型化变体的投影定义:
var builder = Builders<Flower>.Projection; var projection = builder.Include(f => f.Name).Include(f => f.Price).Exclude(f => f.Id);
还可以使用基于字符串的字段名称来定义投影:
var builder = Builders<Flower>.Projection; var projection = builder.Include("Name").Include("Price").Exclude("Id");
最后,可以使用 Expression()
方法定义投影:
var builder = Builders<Flower>.Projection; var projection = builder.Expression(f => new { Name = f.Name, Price = f.Price });
此定义的返回类型为 ProjectionDefinition<TDocument,
TProjection>
,而其他定义会返回 ProjectionDefinition<TDocument>
。
Lambda 表达式
驱动程序支持使用 lambda 表达式渲染投影。使用 Expression()
方法定义 Find()
投影来创建 lambda 表达式时,驱动程序会检查该表达式,确定引用的字段,并自动构造服务器端投影以仅返回这些字段。
还可以使用 lambda 表达式,通过对文档中的值执行操作来创建新字段。以下示例演示如何使用 lambda 表达式通过 Price
和 Stock
字段投影新的 Profit
字段:
var builder = Builders<Flower>.Projection; var projection = builder.Expression(f => new { Profit = f.Price * f.Stock });
注意
排除 Id 字段
使用 lambda 表达式创建投影时,输出会自动排除Id
字段,除非您明确将 is 作为投影字段包括在内。
定义排序
SortDefinitionBuilder
类提供了一个类型安全的接口,用于构建排序事务语法。假设你要按以下顺序定义排序:
升序
Price
降序
Category
使用构建器创建具有类型化变体的排序定义:
var builder = Builders<Flower>.Sort; var sort = builder.Ascending(f => f.Price).Descending(f => f.Category);
或者可以使用基于字符串的字段名称来定义排序:
var builder = Builders<Flower>.Sort; var sort = builder.Ascending("Price").Descending("Category");
定义更新
UpdateDefinitionBuilder
类提供用于构建更新规范的类型安全接口。假设要使用以下标准创建更新规范:
创建新字段
SunRequirement
将
Price
字段值乘以 0.9
使用构建器创建具有类型化变体的更新规范:
var builder = Builders<Flower>.Update; var update = builder.Set(f => f.SunRequirement, "Full sun").Mul(f => f.Price, 0.9);
或者,可以使用基于字符串的字段名称来定义更新:
var builder = Builders<Flower>.Update; var update = builder.Set("SunRequirement", "Full sun").Mul("Price", 0.9);
定义索引密钥
IndexKeysDefinitionBuilder
类提供用于定义索引键的类型安全接口。假设您想要选择 Category
作为升序索引键。
使用构建器选择带有类型变体的索引键:
var builder = Builders<Flower>.IndexKeys; var keys = builder.Ascending(f => f.Category);
或者,可以使用基于字符串的字段名称来选择索引键:
var builder = Builders<BsonDocument>.IndexKeys; var keys = builder.Ascending("Category");
IndexKeysDefinitionBuilder
类还提供构建通配符索引的方法。可以使用 All field paths
或 A
single field path
创建通配符索引,在本例中使用 Category
:
var builder = Builders<Flower>.IndexKeys; var keys = builder.Wildcard();
var builder = Builders<Flower>.IndexKeys; // Using the typed variant var keys = builder.Wildcard(f => f.Category); // Using string-based field names var keys = builder.Wildcard("Category");
有关如何使用通配符索引的更多信息,请参阅通配符索引。
构建聚合管道
PipelineDefinitionBuilder
类提供用于定义聚合管道的类型安全接口。聚合管道是用于转换文档的一系列阶段。假设要创建管道来执行以下操作:
匹配
Season
字段中包含 "spring" 的所有文档按
Category
字段对结果进行排序按类别对文档进行分组,并显示该类别中所有文档的平均价格和可用总额
使用 PipelineDefinitionBuilder
类构建管道:
var sortBuilder = Builders<Flower>.Sort.Ascending(f => f.Category); var matchFilter = Builders<Flower>.Filter.AnyEq(f => f.Season, "spring"); var pipeline = new EmptyPipelineDefinition<Flower>() .Match(matchFilter) .Sort(sortBuilder) .Group(f => f.Category, g => new { name = g.Key, avgPrice = g.Average(f => f.Price), totalAvailable = g.Sum(f => f.Stock) } );
前面的示例创建了以下管道:
[{ "$match" : { "season" : "spring" } }, { "$sort" : { "category" : 1 } }, { "$group" : { "_id" : "$category", "avgPrice" : { "$avg" : "$price" }, "totalAvailable" : { "$sum" : "$stock" } } }]
您可以将在 PipelineDefinitionBuilder
接口中没有相应类型安全方法的阶段添加到管道中,方法是将查询作为BsonDocument
提供给 AppendStage() 方法。
var pipeline = new EmptyPipelineDefinition<BsonDocument>().AppendStage<BsonDocument, BsonDocument, BsonDocument>("{ $set: { field1: '$field2' } }");
注意
使用BsonDocument
定义管道阶段时,驱动程序不会考虑任何BsonClassMap
、序列化属性或序列化约定。BsonDocument
中使用的字段名必须与服务器上存储的字段名一致。
有关以 BsonDocument
形式提供查询的更多信息,请参阅我们的常见问题解答页面。
要了解有关聚合管道的更多信息,请参阅聚合管道服务器手册页面。
构建 Atlas Search 查询
Search
类提供用于创建 $search 管道阶段的类型安全接口。
要了解如何使用 Search
类来构造搜索查询,请参阅 Atlas Search。
更多信息
在使用示例下查找使用构建器进行各种操作的可运行示例。
API 文档
要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档: