上一篇博客主要介绍了MongoDB和它的的使用场景,这篇文章主要介绍一下如何用C#如何借助官方的Mongodb.Driver操作MongoDB
1.NuGet引入Mongodb.Dirver
安装后项目中会新增如下dll
MongoDB.Driver.dll:顾名思义,驱动程序
MongoDB.Bson.dll:序列化、Json相关
2.初始化集合,子类需重写集合名
#region 构造函数 ////// 集合 /// public string _collName { get; set; } public MongoBaseRepository(string collName) { this._collName = collName; } #endregion
3..初始化链接和数据库
#region 连接配置 ////// 链接 /// private static readonly string conneStr = "mongodb://127.0.0.1:27017"; /// /// 数据库 /// private static readonly string dbName = "TestDb"; #endregion #region 单例创建链接 private static IMongoClient _mongoclient { get; set; } private static IMongoClient CreateClient() { if (_mongoclient == null) { _mongoclient = new MongoClient(conneStr); } return _mongoclient; } #endregion #region 获取链接和数据库 private IMongoClient client = CreateClient(); public IMongoDatabase _database { get { return _mongoclient.GetDatabase(dbName); } } public IMongoDatabase GetDatabase() { return _database; } public IMongoCollection GetClient () where T : class, new() { return _database.GetCollection (_collName); } #endregion
4.操作
Add:
#region +Add 添加一条数据 ////// 添加一条数据 /// /// 添加的实体 /// mongodb连接信息 /// public int Add (T t) where T : class, new() { try { var client = _database.GetCollection (_collName); client.InsertOne(t); return 1; } catch (Exception ex) { return 0; } } #endregion #region +AddAsync 异步添加一条数据 /// /// 异步添加一条数据 /// /// 添加的实体 /// mongodb连接信息 /// public async Task<int> AddAsync (T t) where T : class, new() { try { var client = _database.GetCollection (_collName); await client.InsertOneAsync(t); return 1; } catch { return 0; } } #endregion #region +InsertMany 批量插入 /// /// 批量插入 /// /// mongodb连接信息 /// 实体集合 /// public int InsertMany (List t) where T : class, new() { try { var client = _database.GetCollection (_collName); client.InsertMany(t); return 1; } catch (Exception ex) { return 0; } } #endregion #region +InsertManyAsync 异步批量插入 /// /// 异步批量插入 /// /// mongodb连接信息 /// 实体集合 /// public async Task<int> InsertManyAsync (List t) where T : class, new() { try { var client = _database.GetCollection (_collName); await client.InsertManyAsync(t); return 1; } catch { return 0; } } #endregion
Modify:
#region +Update 修改一条数据 ////// 修改一条数据 /// /// 添加的实体 /// mongodb连接信息 /// public UpdateResult Update (T t, string id, bool isObjectId = true) where T : class, new() { try { var client = _database.GetCollection (_collName); //修改条件 FilterDefinition filter; if (isObjectId) { filter = Builders .Filter.Eq("_id", new ObjectId(id)); } else { filter = Builders .Filter.Eq("_id", id); } //要修改的字段 var list = new List >(); foreach (var item in t.GetType().GetProperties()) { if (item.Name.ToLower() == "id") continue; list.Add(Builders .Update.Set(item.Name, item.GetValue(t))); } var updatefilter = Builders .Update.Combine(list); return client.UpdateOne(filter, updatefilter); } catch (Exception ex) { throw ex; } } #endregion #region +UpdateAsync 异步修改一条数据 /// /// 异步修改一条数据 /// /// 添加的实体 /// mongodb连接信息 /// public async Task UpdateAsync (T t, string id, bool isObjectId) where T : class, new() { try { var client = _database.GetCollection (_collName); //修改条件 FilterDefinition filter; if (isObjectId) { filter = Builders .Filter.Eq("_id", new ObjectId(id)); } else { filter = Builders .Filter.Eq("_id", id); } //要修改的字段 var list = new List >(); foreach (var item in t.GetType().GetProperties()) { if (item.Name.ToLower() == "id") continue; list.Add(Builders .Update.Set(item.Name, item.GetValue(t))); } var updatefilter = Builders .Update.Combine(list); return await client.UpdateOneAsync(filter, updatefilter); } catch (Exception ex) { throw ex; } } #endregion #region +UpdateManay 批量修改数据 /// /// 批量修改数据 /// /// 要修改的字段 /// mongodb连接信息 /// 修改条件 /// public UpdateResult UpdateManay (Dictionary<string, string> dic, FilterDefinition filter) where T : class, new() { try { var client = _database.GetCollection (_collName); T t = new T(); //要修改的字段 var list = new List >(); foreach (var item in t.GetType().GetProperties()) { if (!dic.ContainsKey(item.Name)) continue; var value = dic[item.Name]; list.Add(Builders .Update.Set(item.Name, value)); } var updatefilter = Builders .Update.Combine(list); return client.UpdateMany(filter, updatefilter); } catch (Exception ex) { throw ex; } } #endregion #region +UpdateManayAsync 异步批量修改数据 /// /// 异步批量修改数据 /// /// 要修改的字段 /// mongodb连接信息 /// 修改条件 /// public async Task UpdateManayAsync (Dictionary<string, string> dic, FilterDefinition filter) where T : class, new() { try { var client = _database.GetCollection (_collName); T t = new T(); //要修改的字段 var list = new List >(); foreach (var item in t.GetType().GetProperties()) { if (!dic.ContainsKey(item.Name)) continue; var value = dic[item.Name]; list.Add(Builders .Update.Set(item.Name, value)); } var updatefilter = Builders .Update.Combine(list); return await client.UpdateManyAsync(filter, updatefilter); } catch (Exception ex) { throw ex; } } #endregion
Remove:
#region Delete 删除一条数据 ////// 删除一条数据 /// /// mongodb连接信息 /// objectId /// public DeleteResult Delete (string id, bool isObjectId = true) where T : class, new() { try { var client = _database.GetCollection (_collName); FilterDefinition filter; if (isObjectId) { filter = Builders .Filter.Eq("_id", new ObjectId(id)); } else { filter = Builders .Filter.Eq("_id", id); } return client.DeleteOne(filter); } catch (Exception ex) { throw ex; } } #endregion #region DeleteAsync 异步删除一条数据 /// /// 异步删除一条数据 /// /// mongodb连接信息 /// objectId /// public async Task DeleteAsync (string id, bool isObjectId = true) where T : class, new() { try { var client = _database.GetCollection (_collName); //修改条件 FilterDefinition filter; if (isObjectId) { filter = Builders .Filter.Eq("_id", new ObjectId(id)); } else { filter = Builders .Filter.Eq("_id", id); } return await client.DeleteOneAsync(filter); } catch (Exception ex) { throw ex; } } #endregion #region DeleteMany 删除多条数据 /// /// 删除一条数据 /// /// mongodb连接信息 /// 删除的条件 /// public DeleteResult DeleteMany (FilterDefinition filter) where T : class, new() { try { var client = _database.GetCollection (_collName); return client.DeleteMany(filter); } catch (Exception ex) { throw ex; } } #endregion #region DeleteManyAsync 异步删除多条数据 /// /// 异步删除多条数据 /// /// mongodb连接信息 /// 删除的条件 /// public async Task DeleteManyAsync (FilterDefinition filter) where T : class, new() { try { var client = _database.GetCollection (_collName); return await client.DeleteManyAsync(filter); } catch (Exception ex) { throw ex; } } #endregion
Find:
#region FindOne 根据id查询一条数据 ////// 根据id查询一条数据 /// /// mongodb连接信息 /// objectid /// 要查询的字段,不写时查询全部 /// public T FindOne (string id, bool isObjectId = true, string[] field = null) where T : class, new() { try { var client = _database.GetCollection (_collName); FilterDefinition filter; if (isObjectId) { filter = Builders .Filter.Eq("_id", new ObjectId(id)); } else { filter = Builders .Filter.Eq("_id", id); } //不指定查询字段 if (field == null || field.Length == 0) { return client.Find(filter).FirstOrDefault (); } //制定查询字段 var fieldList = new List >(); for (int i = 0; i < field.Length; i++) { fieldList.Add(Builders .Projection.Include(field[i].ToString())); } var projection = Builders .Projection.Combine(fieldList); fieldList?.Clear(); return client.Find(filter).Project (projection).FirstOrDefault (); } catch (Exception ex) { throw ex; } } #endregion #region FindOneAsync 异步根据id查询一条数据 /// /// 异步根据id查询一条数据 /// /// mongodb连接信息 /// objectid /// public async Task FindOneAsync (string id, bool isObjectId = true, string[] field = null) where T : class, new() { try { var client = _database.GetCollection (_collName); FilterDefinition filter; if (isObjectId) { filter = Builders .Filter.Eq("_id", new ObjectId(id)); } else { filter = Builders .Filter.Eq("_id", id); } //不指定查询字段 if (field == null || field.Length == 0) { return await client.Find(filter).FirstOrDefaultAsync(); } //制定查询字段 var fieldList = new List >(); for (int i = 0; i < field.Length; i++) { fieldList.Add(Builders .Projection.Include(field[i].ToString())); } var projection = Builders .Projection.Combine(fieldList); fieldList?.Clear(); return await client.Find(filter).Project (projection).FirstOrDefaultAsync(); } catch (Exception ex) { throw ex; } } #endregion #region FindList 查询集合 /// /// 查询集合 /// /// mongodb连接信息 /// 查询条件 /// 要查询的字段,不写时查询全部 /// 要排序的字段 /// public List FindList (FilterDefinition filter, string[] field = null, SortDefinition sort = null) where T : class, new() { try { var client = _database.GetCollection (_collName); //不指定查询字段 if (field == null || field.Length == 0) { if (sort == null) return client.Find(filter).ToList(); //进行排序 return client.Find(filter).Sort(sort).ToList(); } //制定查询字段 var fieldList = new List >(); for (int i = 0; i < field.Length; i++) { fieldList.Add(Builders .Projection.Include(field[i].ToString())); } var projection = Builders .Projection.Combine(fieldList); fieldList?.Clear(); if (sort == null) return client.Find(filter).Project (projection).ToList(); //排序查询 return client.Find(filter).Sort(sort).Project (projection).ToList(); } catch (Exception ex) { throw ex; } } #endregion #region FindListAsync 异步查询集合 /// /// 异步查询集合 /// /// mongodb连接信息 /// 查询条件 /// 要查询的字段,不写时查询全部 /// 要排序的字段 /// public async Task > FindListAsync
(FilterDefinition filter, string[] field = null, SortDefinition sort = null) where T : class, new() { try { var client = _database.GetCollection (_collName); //不指定查询字段 if (field == null || field.Length == 0) { if (sort == null) return await client.Find(filter).ToListAsync(); return await client.Find(filter).Sort(sort).ToListAsync(); } //制定查询字段 var fieldList = new List >(); for (int i = 0; i < field.Length; i++) { fieldList.Add(Builders .Projection.Include(field[i].ToString())); } var projection = Builders .Projection.Combine(fieldList); fieldList?.Clear(); if (sort == null) return await client.Find(filter).Project (projection).ToListAsync(); //排序查询 return await client.Find(filter).Sort(sort).Project (projection).ToListAsync(); } catch (Exception ex) { throw ex; } } #endregion #region FindListByPage 分页查询集合 /// /// 分页查询集合 /// /// mongodb连接信息 /// 查询条件 /// 当前页 /// 页容量 /// 总条数 /// 要查询的字段,不写时查询全部 /// 要排序的字段 /// public List FindListByPage (FilterDefinition filter, int pageIndex, int pageSize, out long count, string[] field = null, SortDefinition sort = null) where T : class, new() { try { var client = _database.GetCollection (_collName); count = client.CountDocuments(filter); //不指定查询字段 if (field == null || field.Length == 0) { if (sort == null) return client.Find(filter).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToList(); //进行排序 return client.Find(filter).Sort(sort).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToList(); } //制定查询字段 var fieldList = new List >(); for (int i = 0; i < field.Length; i++) { fieldList.Add(Builders .Projection.Include(field[i].ToString())); } var projection = Builders .Projection.Combine(fieldList); fieldList?.Clear(); //不排序 if (sort == null) return client.Find(filter).Project (projection).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToList(); //排序查询 return client.Find(filter).Sort(sort).Project (projection).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToList(); } catch (Exception ex) { throw ex; } } #endregion #region FindListByPageAsync 异步分页查询集合 /// /// 异步分页查询集合 /// /// mongodb连接信息 /// 查询条件 /// 当前页 /// 页容量 /// 要查询的字段,不写时查询全部 /// 要排序的字段 /// public async Task > FindListByPageAsync
(FilterDefinition filter, int pageIndex, int pageSize, string[] field = null, SortDefinition sort = null) where T : class, new() { try { var client = _database.GetCollection (_collName); //不指定查询字段 if (field == null || field.Length == 0) { if (sort == null) return await client.Find(filter).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync(); //进行排序 return await client.Find(filter).Sort(sort).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync(); } //制定查询字段 var fieldList = new List >(); for (int i = 0; i < field.Length; i++) { fieldList.Add(Builders .Projection.Include(field[i].ToString())); } var projection = Builders .Projection.Combine(fieldList); fieldList?.Clear(); //不排序 if (sort == null) return await client.Find(filter).Project (projection).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync(); //排序查询 return await client.Find(filter).Sort(sort).Project (projection).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync(); } catch (Exception ex) { throw ex; } } #endregion
Count:
#region Count 根据条件获取总数 ////// 根据条件获取总数 /// /// mongodb连接信息 /// 条件 /// public long Count (FilterDefinition filter) where T : class, new() { try { var client = _database.GetCollection (_collName); return client.CountDocuments(filter); } catch (Exception ex) { throw ex; } } #endregion #region CountAsync 异步根据条件获取总数 /// /// 异步根据条件获取总数 /// /// mongodb连接信息 /// 条件 /// public async Task<long> CountAsync ( FilterDefinition filter) where T : class, new() { try { var client = _database.GetCollection (_collName); return await client.CountDocumentsAsync(filter); } catch (Exception ex) { throw ex; } } #endregion
查询实例:
public async Task> MyMessage(BaseCondition condition) { //根据时间排序 var sort = Builders .Sort.Ascending("State"); var list = new List >(); list.Add(Builders .Filter.Eq("ReciveCode","admin")); //>开始时间 <结束时间 if (!string.IsNullOrEmpty(condition.startTime) && !string.IsNullOrEmpty(condition.endTime)) { list.Add(Builders .Filter.Gte("CreateDate", condition.startTime)); list.Add(Builders .Filter.Lte("CreateDate", condition.endTime)); } //Or条件 if (!string.IsNullOrEmpty(condition.SerachCondition)) { var list_or = new List >(); list_or.Add(Builders .Filter.Regex("Title", condition.SerachCondition)); list_or.Add(Builders .Filter.Regex("MContent", condition.SerachCondition)); list_or.Add(Builders .Filter.Regex("SendCode", condition.SerachCondition)); list.Add(Builders .Filter.Or(list_or)); } var filter = Builders .Filter.And(list); var result = await base.FindListAsync (filter, null, sort); return result; }
时间格式需要序列化,如下
5.ObjectId详解
MongoDB中我们经常会接触到一个自动生成的字段:”_id”,类型为ObjectId。
ObjectId构成
之前我们使用MySQL等关系型数据库时,主键都是设置成自增的。但在分布式环境下,这种方法就不可行了,会产生冲突。为此,MongoDB采用了一个称之为ObjectId的类型来做主键。ObjectId是一个12字节的 BSON 类型字符串。按照字节顺序,一次代表:
4字节:UNIX时间戳
3字节:表示运行MongoDB的机器
2字节:表示生成此_id的进程
3字节:由一个随机数开始的计数器生成的值
从ObjectId的构造上来看,内部就嵌入了时间类型。我们肯定可以从中获取时间信息:即插入此文档时的时间。MongoDB对ObjectId对象提供了getTimestamp()方法来获取ObjectId的时间。
6.注意事项:
平均插入速率:MongoDB不指定_id插入 > MongoDB指定_id插入。
分析:
在MongoDB中,指定索引插入比不指定慢很多,这是因为,MongoDB里每一条数据的_id值都是唯一的。当在不指定_id插入数据的时候,其_id是系统自动计算生成的。MongoDB通过计算机特征值、时间、进程ID与随机数来确保生成的_id是唯一的。而在指定_id插入时,MongoDB每插一条数据,都需要检查此_id可不可用,当数据库中数据条数太多的时候,这一步的查询开销会拖慢整个数据库的插入速度。如果想充分利用MongoDB性能的话,推荐采取不带”_id”的插入方式