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
}
}