using MongoDB.Bson; using MongoDB.Driver; using MongoDB.Driver.Builders; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace Ant.Service.Mongodb { /// /// Mongo db的数据库帮助类 /// public class MongoDbHelper { /// /// 数据库的实例 /// private MongoDatabase _db; /// /// ObjectId的键 /// private readonly string OBJECTID_KEY = "_id"; public MongoDbHelper(string host, string timeOut) { this._db = new MongoDb(host, timeOut).GetDataBase(); } public MongoDbHelper(MongoDatabase db) { this._db = db; } #region 查询实例 //Query.All(“name”, “a”, “b”);//通过多个元素来匹配数组 //Query.And(Query.EQ(“name”, “a”), Query.EQ(“title”, “t”));//同时满足多个条件 //Query.EQ(“name”, “a”);//等于 //Query.Exists(“type”, true);//判断键值是否存在 //Query.GT(“value”, 2);//大于> //Query.GTE(“value”, 3);//大于等于>= //Query.In(“name”, “a”, “b”);//包括指定的所有值,可以指定不同类型的条件和值 //Query.LT(“value”, 9);//小于< //Query.LTE(“value”, 8);//小于等于<= //Query.Mod(“value”, 3, 1);//将查询值除以第一个给定值,若余数等于第二个给定值则返回该结果 //Query.NE(“name”, “c”);//不等于 //Query.Nor(Array);//不包括数组中的值 //Query.Not(“name”);//元素条件语句 //Query.NotIn(“name”, “a”, 2);//返回与数组中所有条件都不匹配的文档 //Query.Or(Query.EQ(“name”, “a”), Query.EQ(“title”, “t”));//满足其中一个条件 //Query.Size(“name”, 2);//给定键的长度 //Query.Type(“_id”, BsonType.ObjectId);//给定键的类型 //Query.Where(BsonJavaScript);//执行JavaScript //Query.Matches(“Title”, str);//模糊查询 相当于sql中like – str可包含正则表达式 #endregion public T GetNextSequence(IMongoQuery query, SortByDocument sortBy, UpdateDocument update, string collectionName, string indexName) { if (this._db == null) { return default(T); } try { MongoCollection mc = this._db.GetCollection(collectionName); query = this.InitQuery(query); sortBy = this.InitSortBy(sortBy, OBJECTID_KEY); update = this.InitUpdateDocument(update, indexName); var ido = mc.FindAndModify(query, sortBy, update, true, false); return ido.GetModifiedDocumentAs(); } catch (Exception ex) { return default(T); } } #region 插入数据 /// /// 将数据插入进数据库 /// /// 需要插入数据的类型 /// 需要插入的具体实体 public bool Insert(T t) { //集合名称 string collectionName = typeof(T).Name; return Insert(t, collectionName); } /// /// 将数据插入进数据库 /// /// 需要插入数据库的实体类型 /// 需要插入数据库的具体实体 /// 指定插入的集合 public bool Insert(T t, string collectionName) { if (this._db == null) { return false; } try { MongoCollection mc = this._db.GetCollection(collectionName); //将实体转换为bson文档 BsonDocument bd = t.ToBsonDocument(); //进行插入操作 WriteConcernResult result = mc.Insert(bd); if (!string.IsNullOrEmpty(result.ErrorMessage)) { return false; } return true; } catch (Exception ex) { return false; } } /// /// 批量插入数据 /// /// 需要插入数据库的实体类型 /// 需要插入数据的列表 public bool Insert(List list) { //集合名称 string collectionName = typeof(T).Name; return this.Insert(list, collectionName); } /// /// 批量插入数据 /// /// 需要插入数据库的实体类型 /// 需要插入数据的列表 /// 指定要插入的集合 public bool Insert(List list, string collectionName) { if (this._db == null) { return false; } try { MongoCollection mc = this._db.GetCollection(collectionName); //创建一个空间bson集合 List bsonList = new List(); //批量将数据转为bson格式 并且放进bson文档 list.ForEach(t => bsonList.Add(t.ToBsonDocument())); //批量插入数据 mc.InsertBatch(bsonList); return true; } catch (Exception ex) { return false; } } #endregion #region 查询数据 #region 查询所有记录 /// /// 查询一个集合中的所有数据 /// /// 该集合数据的所属类型 /// 指定集合的名称 /// 返回一个List列表 public List FindAll(string collectionName) { if (this._db == null) { return null; } try { MongoCollection mc = this._db.GetCollection(collectionName); //以实体方式取出其数据集合 MongoCursor mongoCursor = mc.FindAll(); //直接转化为List返回 return mongoCursor.ToList(); } catch (Exception ex) { return null; } } /// /// 查询一个集合中的所有数据 其集合的名称为T的名称 /// /// 该集合数据的所属类型 /// 返回一个List列表 public List FindAll() { string collectionName = typeof(T).Name; return FindAll(collectionName); } #endregion #region 查询一条记录 /// /// 查询索引最大的一条记录 /// /// 该数据所属的类型 /// 去指定查询的集合 /// 排序字段 /// 返回一个实体类型 public T FindOneToIndexMax(string[] sort) { string collectionName = typeof(T).Name; return FindOneToIndexMax(null, collectionName, sort); } /// /// 查询索引最大的一条记录 /// /// 该数据所属的类型 /// 去指定查询的集合 /// 排序字段 /// 返回一个实体类型 public T FindOneToIndexMax(IMongoQuery query, string[] sort) { string collectionName = typeof(T).Name; return FindOneToIndexMax(query, collectionName, sort); } /// /// 查询索引最大的一条记录 /// /// 该数据所属的类型 /// 去指定查询的集合 /// 排序字段 /// 返回一个实体类型 public T FindOneToIndexMax(string collectionName, string[] sort) { return FindOneToIndexMax(null, collectionName, sort); } /// /// 查询索引最大的一条记录 /// /// 该数据所属的类型 /// 查询的条件 可以为空 /// 去指定查询的集合 /// 排序字段 /// 返回一个实体类型 public T FindOneToIndexMax(IMongoQuery query, string collectionName, string[] sort) { if (this._db == null) { return default(T); } try { MongoCollection mc = this._db.GetCollection(collectionName); query = this.InitQuery(query); //var result = mc.Find(query).SetSkip(20).SetLimit(10).SetSortOrder(SortBy.Ascending("CreateOn")).ToList(); T t = mc.Find(query).SetSortOrder(SortBy.Descending(sort)).FirstOrDefault(); return t; } catch (Exception ex) { return default(T); } } /// /// 查询索引最大的一条记录 /// /// 该数据所属的类型 /// 查询的条件 可以为空 /// 去指定查询的集合 /// 排序字段 /// 返回一个实体类型 public T FindOneToIndexMaxAsc(IMongoQuery query, string collectionName, string[] sort) { if (this._db == null) { return default(T); } try { MongoCollection mc = this._db.GetCollection(collectionName); query = this.InitQuery(query); //var result = mc.Find(query).SetSkip(20).SetLimit(10).SetSortOrder(SortBy.Ascending("CreateOn")).ToList(); T t = mc.Find(query).SetSortOrder(SortBy.Ascending(sort)).FirstOrDefault(); return t; } catch (Exception ex) { return default(T); } } /// /// 查询一条记录 /// /// 该数据所属的类型 /// 查询的条件 可以为空 /// 去指定查询的集合 /// 返回一个实体类型 public T FindOne(IMongoQuery query, string collectionName) { if (this._db == null) { return default(T); } try { MongoCollection mc = this._db.GetCollection(collectionName); query = this.InitQuery(query); T t = mc.FindOne(query); return t; } catch (Exception ex) { return default(T); } } /// /// 查询一条记录 /// /// 该数据所属的类型 /// 去指定查询的集合 /// 返回一个实体类型 public T FindOne(string collectionName) { return FindOne(null, collectionName); } /// /// 查询一条记录 /// /// 该数据所属的类型 /// 返回一个实体类型 public T FindOne() { string collectionName = typeof(T).Name; return FindOne(null, collectionName); } /// /// 查询一条记录 /// /// 该数据所属的类型 /// 查询的条件 可以为空 /// 返回一个实体类型 public T FindOne(IMongoQuery query) { string collectionName = typeof(T).Name; return FindOne(query, collectionName); } #endregion #region 普通的条件查询 /// /// 根据指定条件查询集合中的数据 /// /// 该集合数据的所属类型 /// 指定的查询条件 比如Query.And(Query.EQ("username","admin"),Query.EQ("password":"admin")) /// 指定的集合的名称 /// 返回一个List列表 public List Find(IMongoQuery query, string collectionName) { if (this._db == null) { return null; } try { MongoCollection mc = this._db.GetCollection(collectionName); query = this.InitQuery(query); MongoCursor mongoCursor = mc.Find(query); return mongoCursor.ToList(); } catch (Exception ex) { return null; } } /// /// 根据指定条件查询集合中的数据 /// /// 该集合数据的所属类型 /// 指定的查询条件 比如Query.And(Query.EQ("username","admin"),Query.EQ("password":"admin")) /// 返回一个List列表 public List Find(IMongoQuery query) { string collectionName = typeof(T).Name; return this.Find(query, collectionName); } #endregion #region 分页查询 PageIndex和PageSize模式 在页数PageIndex大的情况下 效率明显变低 /// /// 分页查询 PageIndex和PageSize模式 在页数PageIndex大的情况下 效率明显变低 /// /// 所需查询的数据的实体类型 /// 查询的条件 /// 当前的页数 /// 当前的尺寸 /// 排序方式 /// 集合名称 /// 返回List列表 public List Find(IMongoQuery query, int pageIndex, int pageSize, SortByDocument sortBy, string collectionName) { if (this._db == null) { return null; } try { MongoCollection mc = this._db.GetCollection(collectionName); MongoCursor mongoCursor = null; query = this.InitQuery(query); sortBy = this.InitSortBy(sortBy, OBJECTID_KEY); //如页序号为0时初始化为1 pageIndex = pageIndex == 0 ? 1 : pageIndex; //按条件查询 排序 跳数 取数 mongoCursor = mc.Find(query).SetSortOrder(sortBy).SetSkip((pageIndex - 1) * pageSize).SetLimit(pageSize); return mongoCursor.ToList(); } catch (Exception ex) { return null; } } /// /// 分页查询 PageIndex和PageSize模式 在页数PageIndex大的情况下 效率明显变低 /// /// 所需查询的数据的实体类型 /// 查询的条件 /// 当前的页数 /// 当前的尺寸 /// 排序方式 /// 返回List列表 public List Find(IMongoQuery query, int pageIndex, int pageSize, SortByDocument sortBy) { string collectionName = typeof(T).Name; return this.Find(query, pageIndex, pageSize, sortBy, collectionName); } #endregion #region 分页查询 指定索引最后项-PageSize模式 /// /// 分页查询 指定索引最后项-PageSize模式 /// /// 所需查询的数据的实体类型 /// 查询的条件 没有可以为null /// 索引名称 /// 最后索引的值 /// 分页的尺寸 /// 排序类型 1升序 -1降序 仅仅针对该索引 /// 指定的集合名称 /// 返回一个List列表数据 public List Find(IMongoQuery query, string indexName, object lastKeyValue, int pageSize, int sortType, string collectionName) { if (this._db == null) { return null; } try { MongoCollection mc = this._db.GetCollection(collectionName); MongoCursor mongoCursor = null; query = this.InitQuery(query); //判断升降序后进行查询 if (sortType > 0) { //升序 if (lastKeyValue != null) { //有上一个主键的值传进来时才添加上一个主键的值的条件 query = Query.And(query, Query.GT(indexName, BsonValue.Create(lastKeyValue))); } //先按条件查询 再排序 再取数 mongoCursor = mc.Find(query).SetSortOrder(new SortByDocument(indexName, 1)).SetLimit(pageSize); } else { //降序 if (lastKeyValue != null) { query = Query.And(query, Query.LT(indexName, BsonValue.Create(lastKeyValue))); } mongoCursor = mc.Find(query).SetSortOrder(new SortByDocument(indexName, -1)).SetLimit(pageSize); } return mongoCursor.ToList(); } catch (Exception ex) { return null; } } /// /// 分页查询 指定索引最后项-PageSize模式 /// /// 所需查询的数据的实体类型 /// 查询的条件 没有可以为null /// 索引名称 /// 最后索引的值 /// 分页的尺寸 /// 排序类型 1升序 -1降序 仅仅针对该索引 /// 返回一个List列表数据 public List Find(IMongoQuery query, string indexName, object lastKeyValue, int pageSize, int sortType) { string collectionName = typeof(T).Name; return this.Find(query, indexName, lastKeyValue, pageSize, sortType, collectionName); } /// /// 分页查询 指定ObjectId最后项-PageSize模式 /// /// 所需查询的数据的实体类型 /// 查询的条件 没有可以为null /// 上一条记录的ObjectId 没有可以为空 /// 每页尺寸 /// 排序类型 1升序 -1降序 仅仅针对_id /// 指定去查询集合的名称 /// 返回一个List列表数据 public List Find(IMongoQuery query, string lastObjectId, int pageSize, int sortType, string collectionName) { return this.Find(query, OBJECTID_KEY, new ObjectId(lastObjectId), pageSize, sortType, collectionName); } /// /// 分页查询 指定ObjectId最后项-PageSize模式 /// /// 所需查询的数据的实体类型 /// 查询的条件 没有可以为null /// 上一条记录的ObjectId 没有可以为空 /// 每页尺寸 /// 排序类型 1升序 -1降序 仅仅针对_id /// 返回一个List列表数据 public List Find(IMongoQuery query, string lastObjectId, int pageSize, int sortType) { string collectionName = typeof(T).Name; return Find(query, lastObjectId, pageSize, sortType, collectionName); } #endregion #endregion #region 更新数据 /// /// 更新数据 /// /// 更新的数据 所属的类型 /// 更新数据的查询 /// 需要更新的文档 /// 指定更新集合的名称 public bool Update(IMongoQuery query, IMongoUpdate update, string collectionName) { if (this._db == null) { return false; } try { MongoCollection mc = this._db.GetCollection(collectionName); query = this.InitQuery(query); //更新数据 WriteConcernResult result = mc.Update(query, update, UpdateFlags.Multi); return true; } catch (Exception ex) { return false; } } ///// ///// 更新数据 ///// //public bool Update(string collectionName, Expression> t) //{ // var col = this._db.GetCollection(collectionName); // //查出Name值为xumingxiang的第一条记录 // T users = col.FindOne(t); // object obj = new object(); // //或者 // //Users users = col.FindOne(new Document { { "Name", "xumingxiang" } }); //} /// /// 更新数据 /// /// 更新的数据 所属的类型 /// 更新数据的查询 /// 需要更新的文档 public bool Update(IMongoQuery query, IMongoUpdate update) { string collectionName = typeof(T).Name; return this.Update(query, update, collectionName); } #endregion #region 移除/删除数据 /// /// 移除指定的数据 /// /// 移除的数据类型 /// 移除的数据条件 /// 指定的集合名词 public bool Remove(IMongoQuery query, string collectionName) { if (this._db == null) { return false; } try { MongoCollection mc = this._db.GetCollection(collectionName); query = this.InitQuery(query); //根据指定查询移除数据 mc.Remove(query); return true; } catch (Exception ex) { return false; } } /// /// 移除指定的数据 /// /// 移除的数据类型 /// 移除的数据条件 public bool Remove(IMongoQuery query) { string collectionName = typeof(T).Name; return this.Remove(query, collectionName); } /// /// 移除实体里面所有的数据 /// /// 移除的数据类型 public bool ReomveAll() { string collectionName = typeof(T).Name; return this.Remove(null, collectionName); } /// /// 移除实体里面所有的数据 /// /// 移除的数据类型 /// 指定的集合名称 public bool RemoveAll(string collectionName) { return this.Remove(null, collectionName); } #endregion #region 创建索引 /// /// 创建索引 /// /// 需要创建索引的实体类型 public bool CreateIndex() { if (this._db == null) { return false; } try { string collectionName = typeof(T).Name; MongoCollection mc = this._db.GetCollection(collectionName); PropertyInfo[] propertys = typeof(T).GetProperties(BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty); //得到该实体类型的属性 foreach (PropertyInfo property in propertys) { //在各个属性中得到其特性 foreach (object obj in property.GetCustomAttributes(true)) { MongoDbFieldAttribute mongoField = obj as MongoDbFieldAttribute; if (mongoField != null) {// 此特性为mongodb的字段属性 IndexKeysBuilder indexKey; if (mongoField.Ascending) { //升序 索引 indexKey = IndexKeys.Ascending(property.Name); } else { //降序索引 indexKey = IndexKeys.Descending(property.Name); } //创建该属性 mc.CreateIndex(indexKey, IndexOptions.SetUnique(mongoField.Unique)); } } } return true; } catch (Exception ex) { return false; } } #endregion #region 获取表的行数 /// /// 获取数据表总行数 /// /// /// /// /// public long GetCount(IMongoQuery query, string collectionName) { if (this._db == null) { return 0; } try { MongoCollection mc = this._db.GetCollection(collectionName); if (query == null) { return mc.Count(); } else { return mc.Count(query); } } catch (Exception ex) { return 0; } } /// /// 获取数据表总行数 /// /// /// /// public long GetCount(IMongoQuery query) { string collectionName = typeof(T).Name; return GetCount(query, collectionName); } #endregion #region 获取集合的存储大小 /// /// 获取集合的存储大小 /// /// 该集合对应的实体类 /// 返回一个long型 public long GetDataSize() { string collectionName = typeof(T).Name; return GetDataSize(collectionName); } /// /// 获取集合的存储大小 /// /// 该集合对应的名称 /// 返回一个long型 public long GetDataSize(string collectionName) { if (this._db == null) { return 0; } try { MongoCollection mc = this._db.GetCollection(collectionName); return mc.GetTotalStorageSize(); } catch (Exception ex) { return 0; } } #endregion #region 私有的一些辅助方法 /// /// 初始化查询记录 主要当该查询条件为空时 会附加一个恒真的查询条件,防止空查询报错 /// /// 查询的条件 /// private IMongoQuery InitQuery(IMongoQuery query) { if (query == null) { //当查询为空时 附加恒真的条件 类似SQL:1=1的语法 query = Query.Exists(OBJECTID_KEY); } return query; } /// /// 初始化排序条件 主要当条件为空时 会默认以ObjectId递增的一个排序 /// /// /// /// private SortByDocument InitSortBy(SortByDocument sortBy, string sortByName) { if (sortBy == null) { //默认ObjectId 递增 sortBy = new SortByDocument(sortByName, -1); } return sortBy; } private UpdateDocument InitUpdateDocument(UpdateDocument update, string indexName) { if (update == null) { update = new UpdateDocument("$inc", new QueryDocument(indexName, 0)); } return update; } #endregion } }