直接上代码
MongoDB.Driver包提供的LINQ查询语法。以下是一个使用C#和MongoDB进行多条件查询、多表联查的示例代码:
多条件查询,多表关联
using MongoDB.Driver;
using MongoDB.Bson;
using System.Linq;
namespace MyMongoDBDemo
{
class Program
{
static void Main(string[] args)
{
string connectionString = "mongodb://localhost:27017";
MongoClient mongoClient = new MongoClient(connectionString);
var database = mongoClient.GetDatabase("mydatabase");
// 获取集合
var ordersCollection = database.GetCollection<BsonDocument>("orders");
var customersCollection = database.GetCollection<BsonDocument>("customers");
// 多条件查询 orders 集合
var filter = Builders<BsonDocument>.Filter.And(
Builders<BsonDocument>.Filter.Eq("status", "active"),
Builders<BsonDocument>.Filter.Gte("totalAmount", 100));
var orders = ordersCollection.Find(filter).ToList();
foreach (var order in orders)
{
// 获取关联的 customer 记录
var customerId = order.GetValue("customerId").ToString();
var customerFilter = Builders<BsonDocument>.Filter.Eq("_id", ObjectId.Parse(customerId));
var customer = customersCollection.Find(customerFilter).FirstOrDefault();
// 处理数据
// ...
}
// 多表联查
var results = from order in ordersCollection.AsQueryable()
join customer in customersCollection.AsQueryable() on order.GetValue("customerId").ToString() equals customer.GetValue("_id").ToString()
select new
{
OrderId = order.GetValue("_id").ToString(),
CustomerName = customer.GetValue("name").ToString()
};
foreach (var result in results)
{
// 处理数据
// ...
}
}
}
}
多表关联并且多条件查询
可以使用 MongoDB 的聚合管道(Aggregation Pipeline)来实现多表关联并且多条件查询的操作。以下是一个示例代码,假设有两个集合分别是“orders”和“customers”,它们的文档结构如下:
orders 集合:
{
"_id": ObjectId("609f99c81de502c6a4f5299b"),
"order_id": 10001,
"customer_id": 20001,
"order_date": "2022-05-01",
"total_amount": 100.0
}
customers 集合:
{
"_id": ObjectId("609f99c81de502c6a4f5299c"),
"customer_id": 20001,
"customer_name": "张三",
"customer_email": "zhangsan@example.com"
}
从上述数据结构可知,orders 集合中的 customer_id 字段与 customers 集合中的 customer_id 字段关联。
查询需求:查找 2022 年 5 月 1 日以后下单金额大于等于 50 元的订单信息,并返回订单所属客户的姓名和邮箱。
代码实现如下:
csharp
using MongoDB.Driver;
using MongoDB.Bson;
var client = new MongoClient("mongodb://localhost:27017");
var database = client.GetDatabase("mydb");
var ordersCollection = database.GetCollection<BsonDocument>("orders");
var customersCollection = database.GetCollection<BsonDocument>("customers");
var pipeline = new BsonDocument[]
{
// 过滤条件:订单日期在 2022 年 5 月 1 日以后,订单金额大于等于 50 元
new BsonDocument("$match", new BsonDocument
{
{ "order_date", new BsonDocument("$gte", new BsonDateTime(new DateTime(2022, 5, 1))) },
{ "total_amount", new BsonDocument("$gte", 50.0) }
}),
// 关联 customers 集合,并按 customer_id 分组
new BsonDocument("$lookup", new BsonDocument
{
{ "from", "customers" }, // 连接的集合名称
{ "localField", "customer_id" }, // 当前集合的关联字段
{ "foreignField", "customer_id" }, // 目标集合的关联字段
{ "as", "customer_info" } // 输出结果中的新字段名
}),
// 过滤条件:存在客户信息(即 customers 集合中存在对应的文档)
new BsonDocument("$match", new BsonDocument
{
{ "customer_info", new BsonDocument("$ne", new BsonArray()) }
}),
// 投影出返回结果需要的字段
new BsonDocument("$project", new BsonDocument
{
{ "_id", 0 },
{ "customer_name", "$customer_info.customer_name" },
{ "customer_email", "$customer_info.customer_email" },
{ "order_id", 1 },
{ "total_amount", 1 }
})
};
var result = ordersCollection.Aggregate<BsonDocument>(pipeline).ToList();
在上面的代码中,我们首先从 MongoDB 客户端获取了 orders 和 customers 两个集合的引用,然后使用聚合管道进行多表关联查询。具体而言,聚合管道的操作包括:
$match 操作:过滤出订单日期在 2022 年 5 月 1 日以后、订单金额大于等于 50 元的订单。
$lookup 操作:将上一步得到的订单和 customers 集合关联起来,按照 customer_id 分组。
$match 操作:过滤出存在客户信息的订单。
$project 操作:投影出需要返回的字段(即客户姓名、邮箱、订单号和总金额)。
最后,我们使用 ToList() 方法将查询结果转换成一个 List 类型的对象,并存储在变量 result 中。
多表关联并且多条件查询,使用lambda表达式
using MongoDB.Driver;
using MongoDB.Bson;
var client = new MongoClient("mongodb://localhost:27017"); // 连接 MongoDB 服务
var database = client.GetDatabase("mydb"); // 获取数据库实例
var ordersCollection = database.GetCollection<BsonDocument>("orders"); // 获取 orders 集合实例
var customersCollection = database.GetCollection<BsonDocument>("customers"); // 获取 customers 集合实例
var result = ordersCollection.Aggregate()
.Lookup("customers", "customer_id", "customer_id", "customer_info") // $lookup 管道操作
.Unwind("customer_info") // $unwind 管道操作
.Match(Builders<BsonDocument>.Filter.And( // $match 管道操作,多条件查询
Builders<BsonDocument>.Filter.Gte("order_date", new BsonDateTime(new DateTime(2023, 1, 1))), // 订单日期大于等于指定日期
Builders<BsonDocument>.Filter.Lte("order_date", new BsonDateTime(new DateTime(2023, 2, 1))), // 订单日期小于等于指定日期
Builders<BsonDocument>.Filter.ElemMatch<BsonValue>("items", Builders<BsonValue>.Filter.Eq("product_name", "iPhone 14")), // 订单中包含商品名称为 iPhone 14 的商品
Builders<BsonDocument>.Filter.Eq("customer_info.customer_name", "张三") // 客户姓名为张三
))
.Project<OrderCustomer>(p => new OrderCustomer // $project 管道操作
{
OrderId = p["order_id"].AsInt32,
CustomerName = p["customer_info"]["customer_name"].AsString,
CustomerEmail = p["customer_info"]["customer_email"].AsString,
TotalAmount = p["total_amount"].AsDouble
})
.ToList();
public class OrderCustomer // 查询结果对象的定义
{
public int OrderId { get; set; }
public string CustomerName { get; set; }
public string CustomerEmail { get; set; }
public double TotalAmount { get; set; }
}
在上述代码中,我们使用了 MongoDB 的 Aggregate 方法和一系列 Lambda 表达式来实现多表关联并且多条件查询。具体而言,Lambda 表达式包括:
.Lookup 方法:连接 customers 集合,并将匹配的文档作为 customer_info 数组字段添加到输出文档。
.Unwind 方法:展开 customer_info 数组字段,以便进行后续的筛选操作。
.Match 方法:根据多个条件对数据进行筛选,这里使用了 And 运算符组合多个 Filters。其中:
Builders.Filter.Gte(“order_date”, new BsonDateTime(new DateTime(2023, 1, 1))):订单日期大于等于 2023 年 1 月 1 日。
Builders.Filter.Lte(“order_date”, new BsonDateTime(new DateTime(2023, 2, 1))):订单日期小于等于 2023 年 2 月 1 日。
Builders.Filter.ElemMatch(“items”, Builders.Filter.Eq(“product_name”, “iPhone 14”)):订单中包含商品名称为 iPhone 14 的商品。
Builders.Filter.Eq(“customer_info.customer_name”, “张三”):客户姓名为张三。
.Project 方法:投影输出文档的字段,创建一个自定义类型 OrderCustomer 实例,包括订单号、客户姓名、客户邮箱和总金额等字段。
最后,我们调用 ToList() 方法将查询结果转换成一个 List 类型的对象,并存储在变量 result 中。如果需要更改查询条件或者查询结果的类型,则可以修改相应的 Lambda 表达式。
动态过滤
Builders.Filter是MongoDB .NET Driver提供的用于动态创建过滤器的静态类。下面是常用的几个Filter方法及其用法:
Eq 用法:Builders.Filter.Eq(fieldName, value)
说明:生成一个用于判断某个字段等于指定值value的过滤器。
示例:Builders.Filter.Eq(“Level”, “ERROR”) 判断Level字段是否等于”ERROR”
Lt 用法:Builders.Filter.Lt(fieldName, value)
说明:生成一个用于判断某个字段小于指定值value的过滤器。
示例:Builders.Filter.Lt(“Timestamp”, DateTime.Today) 判断Timestamp字段是否小于今天
Gt 用法:Builders.Filter.Gt(fieldName, value)
说明:生成一个用于判断某个字段大于指定值value的过滤器。
示例:Builders.Filter.Gt(“Timestamp”, DateTime.Today.AddDays(-7)) 判断Timestamp字段是否大于7天前
Lte 用法:Builders.Filter.Lte(fieldName, value)
说明:生成一个用于判断某个字段小于等于指定值value的过滤器。
示例:Builders.Filter.Lte(“Timestamp”, DateTime.Today) 判断Timestamp字段是否小于等于今天
Gte 用法:Builders.Filter.Gte(fieldName, value)
说明:生成一个用于判断某个字段大于等于指定值value的过滤器。
示例:Builders.Filter.Gte(“Timestamp”, DateTime.Today.AddDays(-7)) 判断Timestamp字段是否大于等于7天前
And 用法:Builders.Filter.And(filter1, filter2, …)
说明:生成一个用于同时满足多个过滤器条件的过滤器。
示例:Builders.Filter.And( Builders.Filter.Eq(“Level”, “ERROR”), Builders.Filter.Gte(“Timestamp”, DateTime.Today) ) 判断Level字段是否等于”ERROR”且Timestamp字段大于等于今天
Or 用法:Builders.Filter.Or(filter1, filter2, …)
说明:生成一个用于满足多个过滤器条件之一的过滤器。
示例:Builders.Filter.Or( Builders.Filter.Eq(“Level”, “ERROR”), Builders.Filter.Gte(“Timestamp”, DateTime.Today) ) 判断Level字段等于”ERROR”或Timestamp字段大于等
清空集合,删除数据库
IMongoCollection<BsonDocument> collection = database.GetCollection<BsonDocument>("mycollection");
collection.DeleteMany(Builders<BsonDocument>.Filter.Empty);
标题清除数据库
string connectionString = "mongodb://localhost:27017";
MongoClient mongoClient = new MongoClient(connectionString);
mongoClient.DropDatabase("mydatabase");
BsonDocument转成普通的实体对象
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
public class Person
{
[BsonId]
public ObjectId Id { get; set; }
[BsonElement("name")]
public string Name { get; set; }
[BsonElement("age")]
public int Age { get; set; }
}
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Bson.Serialization;
string connectionString = "mongodb://localhost:27017";
MongoClient mongoClient = new MongoClient(connectionString);
var database = mongoClient.GetDatabase("mydatabase");
var collection = database.GetCollection<BsonDocument>("people");
BsonDocument bsonDocument = collection.Find(x => x["_id"] == new ObjectId("601f501c39e48013f038fd6a")).FirstOrDefault();
var person = BsonSerializer.Deserialize<Person>(bsonDocument);