. NET Framework下使用MongoDB示例
1. 新建一个控制台项目
选择.net framework版本为4.6,最新的mongodb驱动nuget需要达到4.5.2以上,所以选择了4.6版本。
2. 引入nuget包
MongoDB.Driver和MongoDB.Bson
3. MongoDB连接配置
// 连接地址 string connectionStr = "mongodb://localhost:27017"; // 数据库名 string databaseName = "test"; // 表名 string dbName = "tests"; // 创建连接 var mongoClient = new MongoClient(connectionStr); var mongoDb = mongoClient.GetDatabase(databaseName); var collection = mongoDb.GetCollection<User>(dbName);
新建了一个user类
public class User
{
public string _id { get; set; }
public int Age { get; set; }
public string Name { get; set; }
public User Son { get; set; }
public DateTime BirthDateTime { get; set; }
}
4. 简单增删改查
4.1 查询
4.1.1 根据filter字段来查
查询代码
// 过滤条件
var filter = Builders<User>.Filter.Eq(u => u.Name, "CeShi");
var filterALL = Builders<User>.Filter.Where(u => u._id != null);
// 查询结果
var resultList = collection.Find(filterALL).ToList();
Console.WriteLine("查询结果");
int i = 1;
foreach (var result in resultList)
{
Console.WriteLine($"//{i}");
Console.WriteLine("{");
Console.WriteLine($""id":"{result.id}","Age":"{result.Age}","Name":"{result.Name}",");
Console.WriteLine(""Son":{");
if (result.Son != null && result.Son.Age > 0)
{
Console.WriteLine($""Age":"{result.Son.Age}","Name":"{result.Son.Name}"");
}
Console.WriteLine("},");
Console.WriteLine($""BirthDateTime":"{result.BirthDateTime}"");
Console.WriteLine("}");
i++;
}
第一种查询eq方式为根据条件来查的,注意这个时候会区分大小写的。第二种filter是尝试查询全部数据,但是没有找到相关方法,写的一个代替品,因为_id的值是肯定有的,所以这么写了。
第一中查询方式结果

第二种where查询结果

4.1.2 使用linq的方式也可以进行查询
进行全部查询,如
//var query = from u in collection.AsQueryable()
// select new { u.Name, u.age };
var query = from u in collection.AsQueryable()
select u;
var resultList = query.ToList();`
这样查出的结果如下

在linq里可以使用where条件来过滤数据

查询子文档中的数据

4.2 新增
4.2.1 添加一条数据
// 自定义主键
var id = Guid.NewGuid().ToString();
// 要添加的数据实体
var user = new User
{
_id = id,
Age = 26,
Name = "CeShi",
Son = new User
{
Age = 1,
Name = "ceshi"
},
BirthDateTime = DateTime.Now
};
//添加一条数据
collection.InsertOne(user);`
4.2.2 添加多条数据
List<User> userListAdd = new List<User>();
User userAdd1 = new User
{
_id = Guid.NewGuid().ToString(),
Age = 23,
Name = "zhangsan",
BirthDateTime = DateTime.Now.AddYears(-22)
};
userListAdd.Add(userAdd1);
User userAdd2 = new User
{
_id = Guid.NewGuid().ToString(),
Age = 33,
Name = "Adamas",
Son = new User
{
Age = 3,
Name = "Adams",
BirthDateTime = DateTime.Now.AddYears(-2)
},
BirthDateTime = DateTime.Now.AddYears(-32)
};
userListAdd.Add(userAdd2);
// 添加多条使用 InsertMany()方法
collection.InsertMany(userListAdd);
4.3 修改更新
4.3.1 简单更新
使用主键或其他字段进行更新,如将Name为zhagnsan的son赋值
var filter = Builders<User>.Filter.Eq("Name", "zhangsan");
var son = new User {
Age = 2,
Name = "zhangxiao",
BirthDateTime = DateTime.Now.AddYears(-1)
};
// 更新数据
var update = Builders<User>.Update.Set("Son", son);
// 执行更新操作 更新一条数据
UpdateResult upResult = collection.UpdateOne(filter, update);
// 得到更新数据条数
var upCount = upResult.ModifiedCount;`
结果如下

如果想更新多条数据,则配合查询条件,使用collection.UpdateMany
// 过滤条件
var filter = Builders<User>.Filter.Where(u=>u.Name== "CeShi");
// 更新数据
var update = Builders<User>.Update.Set("age", "25");
// 执行更新操作 更新多条
UpdateResult upResult = collection.UpdateMany(filter, update);
// 得到更新数据条数
var upCount=upResult.ModifiedCount;
4.3.2 根据子集合属性更新
根据son的Name的值为“zhangxiao”,将他的年龄修改为4
// 过滤条件
var filter = Builders<User>.Filter.Where(u=>u.Son.Name== "zhangxiao");
var son = new User
{
Age = 4,
Name = "zhangxiao",
BirthDateTime = DateTime.Now.AddYears(-3)
};
// 更新数据
var update = Builders<User>.Update.Set("Son", son);
// 执行更新操作 更新一条数据;更新多条,使用UpdateMany
UpdateResult upResult = collection.UpdateOne(filter, update);
// 得到更新数据条数
var upCount = upResult.ModifiedCount;`
结果如下

4.4 删除
4.4.1 根据主键或其他条件删除
将name为“CeShi”的数据删除
var filter = Builders<User>.Filter.Where(u => u.Name == "CeShi");
// 删除一条数据
DeleteResult deResult = collection.DeleteMany(filter);
// 得到删除条数
var deCount = deResult.DeletedCount;
Console.WriteLine($"删除条数{deCount.ToString()}");
结果查询,已经将name为“CeShi”的数据删除了

4.4.2 根据子集合属性删除
删除子文档son里name为“zhangxiao”的数据
var filter = Builders<User>.Filter.Where(u => u.Son.Name == "zhangxiao");
// 删除一条数据
DeleteResult deResult = collection.DeleteMany(filter);
// 得到删除条数
var deCount = deResult.DeletedCount;
Console.WriteLine($"删除条数{deCount.ToString()}");
结果查询,已经没有子文档son里name为“zhangxiao”的数据了

5. MongoDB命令对应的操作
5.1 $project
$project类似于sql中的select,筛选出我们要的显示字段,如我们想选出所有数据的Name和Age字段
var query = from p in collection.AsQueryable()
select new { p.Name, p.Age };
// 或者
//var query = collection.AsQueryable()
// .Select(p => new { p.Name, p.Age });
结果如下

5.2 $sort
排序。我们根据年龄降序和姓名升序的方式查找数据
var query = from p in collection.AsQueryable()
orderby p.Name, p.Age
descending select p;
// 或者
//var query = collection.AsQueryable() .OrderBy(p => p.Name).ThenByDescending(p => p.Age);
结果如下

5.3 $limit
类似于linq中的take,选取多少条数据
var query = collection.AsQueryable().Take(2);
结果如下

5.4 $skip
类似于linq下的skip,跳过m条数据,配合take使用,即跳过m条数据取n条数据
var query = collection.AsQueryable().Skip(1).Take(1);
结果如下

5.5 $group
分组
var query = from p in collection.AsQueryable()
group p by p.Age into g
select new { Age = g.Key, Count = g.Count() };
// 或者
//var query = collection.AsQueryable()
// .GroupBy(p => p.Age )
// .Select(g => new { Age = g.Key, Count = g.Count() });
结果如下

5.6 $lookup 表联合查询
类似于ef中的左连接
var query = from u in collect.AsQueryable()
join o in coll.AsQueryable() on u.Name equals o.Name
select new { u._id, u.son, o.Id,o.Name };
var result = query.ToList();
由于测试库没有建立第二张表,就简单放一下测试语句
5.7 Distinct
去重。我们查询年龄去重的值
var query = collection.AsQueryable()
.Select(p => new { p.Age })
.Distinct();
结果如下

5.8 其他
请自行参照官方文档,官方文档网址:https://docs.mongodb.com/v3.4/reference/operator/query/
6 c#操作Mongo查询
6.1 插入表结构
新建类
class BsonDocument
{
public ObjectId _id { get; set; }
public string Item { get; set; }
public int Num { get; set; }
public List<ArrayDocument> Instock { get; set; }
}
public class ArrayDocument
{
public string WareHouse { get; set; }
public string Qty { get; set; }
}
插入数据库
var documents = new[] { new BsonDocument{ Item="journal", Num=15, Instock=new List<ArrayDocument>(){ new ArrayDocument { WareHouse = "A", Qty = "5" }, new ArrayDocument { WareHouse = "C", Qty = "15" } } }, new BsonDocument{ Item="notebook", Num=5, Instock=new List<ArrayDocument>(){ new ArrayDocument { WareHouse = "C", Qty = "5" } } }, new BsonDocument{ Item="paper", Num=30, Instock=new List<ArrayDocument>(){ new ArrayDocument { WareHouse = "A", Qty = "60" }, new ArrayDocument { WareHouse = "B", Qty = "15" } } } , new BsonDocument{ Item="planner", Num=22, Instock=new List<ArrayDocument>(){ new ArrayDocument { WareHouse = "A", Qty = "40" }, new ArrayDocument { WareHouse = "B", Qty = "5" } } }, new BsonDocument{ Item="postcard", Num=2, Instock=new List<ArrayDocument>(){ new ArrayDocument { WareHouse = "B", Qty = "15" }, new ArrayDocument { WareHouse = "C", Qty = "35" } } } };
collection.InsertMany(documents);
6.2 普通查询
6.2.1 查询指定item的值
代码
var filter = Builders<BsonDocument>.Filter.Eq("Item", "paper");
var result = collection.Find(filter).ToList();
结果

6.2.2 查询Num值大于1的
代码
var filter = Builders<BsonDocument>.Filter.Gt("Num", 1);
var result = collection.Find(filter).ToList();
结果

6.2.3 and多条件查询
代码
//创建过滤器生成器对象
FilterDefinitionBuilder<BsonDocument> filterBuilder = Builders<BsonDocument>.Filter;
//创建过滤器
var filter = Builders<BsonDocument>.Filter.And(filterBuilder.Gt("Num", 1), filterBuilder.Eq("Item", "notebook"));
var result = collection.Find(filter).ToList();
结果

6.2.4 or多条件查询
代码
//创建过滤器生成器对象
FilterDefinitionBuilder<BsonDocument> filterBuilder = Builders<BsonDocument>.Filter;
//创建过滤器
var filter = Builders<BsonDocument>.Filter.Or(filterBuilder.Gt("Num", 5), filterBuilder.Eq("Item", "notebook"));
var result = collection.Find(filter).ToList();
结果

6.2.5 not查询
查找num小于10
代码
//创建过滤器生成器对象
FilterDefinitionBuilder<BsonDocument> filterBuilder = Builders<BsonDocument>.Filter;
//创建过滤器
var filter = Builders<BsonDocument>.Filter.Not(filterBuilder.Gt("Num", 10));
var result = collection.Find(filter).ToList();
结果

6.2.6 排序
代码
//排序规则 Ascending 正序 Descending 倒序
SortDefinition<BsonDocument> sort = Builders<BsonDocument>.Sort.Descending("Num");
var result = collection.Find(Builders<BsonDocument>.Filter.Empty).Sort(sort).ToList();
结果

6.2.6 in查询
代码
var filter = Builders<BsonDocument>.Filter.In("Item", new[] { "journal", "notebook" });
var result = collection.Find(filter).ToList();
结果

6.2.6 Not In 查询
代码
var filter = Builders<BsonDocument>.Filter.Nin("Item", new[] { "journal", "notebook" });
var result = collection.Find(filter).ToList();
结果

6.2.7 分页查询
代码
//Skip跳过多少页 Limit 获取多少页 var result = collection.Find(Builders<BsonDocument>.Filter.Empty).Skip(1).Limit(1).ToList();
结果

6.2.8 查询总记录数
代码
var result = collection.Find(Builders<BsonDocument>.Filter.Empty).Count();
结果

6.2.9 查询指定属性
代码
ProjectionDefinition<BsonDocument> projection = Builders<BsonDocument>.Projection.Include("Item").Exclude("_id");
var result = collection.Find(Builders<BsonDocument>.Filter.Empty).Project(projection).ToList();
结果

6.3 嵌套查询
6.3.1 条件为嵌套文档字段时加“.”
代码
var filter = Builders<BsonDocument>.Filter.Eq("Instock.WareHouse", "B");
var result = collection.Find(filter).ToList();
结果

6.3.2 嵌套文档数组元素与指定条件匹配的所有文档
顺序必须一致
代码
var filter = Builders<BsonDocument>.Filter.AnyEq("Instock", new ArrayDocument { WareHouse="A" ,Qty="5" });
var result = collection.Find(filter).ToList();
结果

6.3.3 嵌套文档数组中符合其中一个条件的查询
代码
var filter = Builders<BsonDocument>.Filter.Gt("Instock.0.Qty", 15);
var result = collection.Find(filter).ToList();
结果

6.3.4 指定嵌套文档数组索引的元素条件
代码
var filter = Builders<BsonDocument>.Filter.Gt("Instock.0.Qty", 15);
var result = collection.Find(filter).ToList();
结果同上
6.3.5 $ElemMatch查询
嵌套文档数组中至少有一个满足条件
代码
//创建过滤器生成器对象
FilterDefinitionBuilder<BsonDocument> filterBuilder = Builders<BsonDocument>.Filter;
//创建过滤器
FilterDefinition<BsonDocument> filter = filterBuilder.ElemMatch<BsonDocument>("instock", new ArrayDocument{ Qty = "5", WareHouse = "A" });
6.3.6 不使用ElemMatch的多条件查询, 只要文档数组中满足即可
代码
//创建过滤器生成器对象
FilterDefinitionBuilder<BsonDocument> filterBuilder = Builders<BsonDocument>.Filter;
//创建过滤器
FilterDefinition<BsonDocument> filter = filterBuilder.And(filterBuilder.Eq("Instock.Qty",5),filterBuilder.Eq("Instock.WareHouse", "A"));
var result = collection.Find(filter).ToList();
6.3.7 查询嵌套文档中符合要求的嵌套文档数据
使用BsonDocument (奇葩使用)
ProjectionDefinition<BsonDocument> projection = Builders<BsonDocument>.Projection.Include("instock").Exclude("_id");
//unwind 展开数组 AppendStage 添加聚合条件
var result = coll.Aggregate().Unwind("instock").AppendStage<BsonDocument>(new BsonDocument { { "$match", new BsonDocument("instock.qty", new BsonDocument("$gt", 30)) } }
).Project(projection).ToList();
使用强模型 mongo会将decimal类型变成字符串存储 ,所以不可使用decimal类型
准备数据
IList<User> users = new List<User>
{
new User
{
ID = "1",
Name = "狗娃",
Age = 11,
Order = new List<Order>
{
new Order{Name="订单1",Price=111},
new Order{Name="订单2",Price=222},
new Order{Name="订单3",Price=333},
}
},
new User
{
ID = "2",
Name = "铁蛋",
Age = 11,
Order = new List<Order>
{
new Order{Name="订单4",Price=666},
new Order{Name="订单5",Price=454},
new Order{Name="订单6",Price=87},
}
},
new User
{
ID = "3",
Name = "狗剩",
Age = 11,
Order = new List<Order>
{
new Order{Name="订单7",Price=1},
new Order{Name="订单8",Price=345},
new Order{Name="订单9",Price=653},
}
}
};
//selectMany 展开子文档数组
var res = coll.AsQueryable().SelectMany(y => y.Order).Where(y=>y.Price>555).ToList();
6.4 查询NULL值属性
6.4.1 数据表
var documents = new[]
{
new BsonDocument { { "_id", 1 }, { "item", BsonNull.Value } },
new BsonDocument { { "_id", 2 } }
};
var documents = new[] {
new BsonDocument {
Item = null
},
new BsonDocument {
}
};
collection.InsertMany(documents);
6.4.2 查询值为null或者不存在的数据
代码
var filter = Builders<BsonDocument>.Filter.Eq("Item", BsonNull.Value);
var result = collection.Find(filter).ToList();
6.4.3 查询值为null的数据
代码
var filter = Builders<BsonDocument>.Filter.Where(u=>u.Item==null);
var result = collection.Find(filter).ToList();
结果

6.4.4 存在检查/查询不存在/存在此属性的值
代码
var filter = Builders<BsonDocument>.Filter.Exists("Item",false);
var result = collection.Find(filter).ToList();
浙公网安备 33010602011771号