using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using MongoDB.Driver.GridFS;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace HH.AMS.BLL.MongoDB
{
///
/// Mongo db的数据库帮助类
///
public class MongoDBHelper
{
///
/// 数据库的实例
///
private MongoDatabase _db;
///
/// ObjectId的键
///
private readonly string OBJECTID_KEY = "_id";
public MongoDBHelper(int type)
{
if (type == 1)
{
this._db = new MongoDB().GetDataBaseOne();
}
if (type == 2)
{
this._db = new MongoDB().GetDataBaseTwo();
}
}
public MongoDBHelper(MongoDatabase db)
{
this._db = db;
}
public MongoDatabase GetMDataBase()
{
return _db;
}
#region 插入数据
///
/// 将数据插入进数据库
///
/// 需要插入数据的类型
/// 需要插入的具体实体
public bool Insert(T t)
{
//集合名称
string collectionName = typeof(T).Name;
return Insert(t, collectionName);
}
///
/// 将数据插入进数据库
///
/// 需要插入数据库的实体类型
/// 需要插入数据库的具体实体
/// 指定插入的集合
public bool Insert(T t, string collectionName)
{
bool isPass = true;
MongoCollection mc = this._db.GetCollection(collectionName);
//将实体转换为json文档
BsonDocument bd = t.ToBsonDocument();
//进行插入操作
WriteConcernResult result = mc.Insert(bd);
if (!string.IsNullOrEmpty(result.ErrorMessage))
{
isPass = false;
throw new Exception(result.ErrorMessage);
}
return isPass;
}
///
/// 批量插入数据
///
/// 需要插入数据库的实体类型
/// 需要插入数据的列表
public bool Insert(List list)
{
//集合名称
string collectionName = typeof(T).Name;
return this.Insert(list, collectionName);
}
///
/// 批量插入数据
///
/// 需要插入数据库的实体类型
/// 需要插入数据的列表
/// 指定要插入的集合
public bool Insert(List list, string collectionName)
{
try
{
MongoCollection mc = this._db.GetCollection(collectionName);
//创建一个空间json集合
List bsonList = new List();
//批量将数据转为json格式 并且放进json文档
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)
{
MongoCollection mc = this._db.GetCollection(collectionName);
//以实体方式取出其数据集合
MongoCursor mongoCursor = mc.FindAll();
//直接转化为List返回
return mongoCursor.ToList();
}
///
/// 查询一个集合中的所有数据 其集合的名称为T的名称
///
/// 该集合数据的所属类型
/// 返回一个List列表
public List FindAll()
{
string collectionName = typeof(T).Name;
return FindAll(collectionName);
}
#endregion
#region 查询一条记录
///
/// 查询一条记录
///
/// 该数据所属的类型
/// 查询的条件 可以为空
/// 去指定查询的集合
/// 返回一个实体类型
public T FindOne(IMongoQuery query, string collectionName)
{
MongoCollection mc = this._db.GetCollection(collectionName);
query = this.InitQuery(query);
T t = mc.FindOne(query);
return 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)
{
MongoCollection mc = this._db.GetCollection(collectionName);
query = this.InitQuery(query);
MongoCursor mongoCursor = mc.Find(query);
return mongoCursor.ToList();
}
///
/// 根据指定条件查询集合中的数据
///
/// 该集合数据的所属类型
/// 指定的查询条件 比如Query.And(Query.EQ("username","admin"),Query.EQ("password":"admin"))
/// 指定的集合的名称
/// 返回一个List列表
public List Find(IMongoQuery query, SortByDocument sortBy, string collectionName)
{
MongoCollection mc = this._db.GetCollection(collectionName);
query = this.InitQuery(query);
MongoCursor mongoCursor = mc.Find(query).SetSortOrder(sortBy);
return mongoCursor.ToList();
}
///
/// 根据指定条件查询集合中的数据记录数
///
/// 该集合数据的所属类型
/// 指定的查询条件 比如Query.And(Query.EQ("username","admin"),Query.EQ("password":"admin"))
/// 指定的集合的名称
/// 返回一个List列表
public long FindCount(IMongoQuery query, string collectionName)
{
MongoCollection mc = this._db.GetCollection(collectionName);
query = this.InitQuery(query);
MongoCursor mongoCursor = mc.Find(query);
return mongoCursor.Count();
}
///
/// 根据指定条件查询集合中的数据
///
/// 该集合数据的所属类型
/// 指定的查询条件 比如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);
}
///
/// 获取前N条数据
///
///
///
///
///
///
///
public List Find(IMongoQuery query, int top, string indexName, string collectionName)
{
MongoCollection mc = this._db.GetCollection(collectionName);
MongoCursor mongoCursor = mc.Find(query).SetLimit(top);
return mongoCursor.ToList();
}
///
/// 获取前N条数据
///
///
///
///
///
///
///
public List Find(IMongoQuery query, int top, string indexName, string collectionName, SortByDocument sortBy)
{
MongoCollection mc = this._db.GetCollection(collectionName);
MongoCursor mongoCursor = mc.Find(query).SetSortOrder(sortBy).SetLimit(top);
return mongoCursor.ToList();
}
#endregion
#region 分页查询 PageIndex和PageSize模式 在页数PageIndex大的情况下 效率明显变低
///
/// 分页查询 PageIndex和PageSize模式 在页数PageIndex大的情况下 效率明显变低
///
/// 所需查询的数据的实体类型
/// 查询的条件
/// 当前的页数
/// 当前的尺寸
/// 排序方式
/// 集合名称
/// 返回List列表
public List Find(IMongoQuery query, int pageIndex, int pageSize, SortByDocument sortBy, string collectionName)
{
MongoCollection mc = this._db.GetCollection(collectionName);
MongoCursor mongoCursor = null;
query = this.InitQuery(query);
sortBy = this.InitSortBy(sortBy);
//如页序号为0时初始化为1
pageIndex = pageIndex == 0 ? 1 : pageIndex;
//按条件查询 排序 跳数 取数
mongoCursor = mc.Find(query).SetSortOrder(sortBy).SetSkip((pageIndex - 1) * pageSize).SetLimit(pageSize);
return mongoCursor.ToList();
}
///
/// 分页查询 PageIndex和PageSize模式 在页数PageIndex大的情况下 效率明显变低
///
/// 所需查询的数据的实体类型
/// 查询的条件
/// 指定查询的字段
/// 当前的页数
/// 当前的尺寸
/// 排序方式
/// 集合名称
/// 返回List列表
public List FindFields(IMongoQuery query, FieldsDocument fd, int pageIndex, int pageSize, SortByDocument sortBy, string collectionName)
{
//try
//{
MongoCollection mc = this._db.GetCollection(collectionName);
MongoCursor mongoCursor = null;
query = this.InitQuery(query);
sortBy = this.InitSortBy(sortBy);
//如页序号为0时初始化为1
pageIndex = pageIndex == 0 ? 1 : pageIndex;
//按条件查询 排序 跳数 取数
mongoCursor = mc.Find(query).SetFields(fd).SetSortOrder(sortBy).SetSkip((pageIndex - 1) * pageSize).SetLimit(pageSize);
return mongoCursor.ToList();
//}
//catch (Exception ex)
//{
// string ss;
// ss = ex.Message.ToString();
//}
//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)
{
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();
}
///
/// 分页查询 指定索引最后项-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 = typeof(T).Name;
return this.Update(query, update, collectionName);
}
///
/// 更新数据
///
/// 更新的数据 所属的类型
/// 更新数据的查询
/// 需要更新的文档
/// 指定更新集合的名称
public bool Update(IMongoQuery query, IMongoUpdate update, string collectionName)
{
try
{
MongoCollection mc = this._db.GetCollection(collectionName);
query = this.InitQuery(query);
//更新数据
WriteConcernResult result = mc.Update(query, update, UpdateFlags.None);
return true;
}
catch (Exception ex)
{
return false;
}
}
#endregion
#region 移除/删除数据
///
/// 移除指定的数据
///
/// 移除的数据类型
/// 移除的数据条件
/// 指定的集合名词
public bool Remove(IMongoQuery query, string collectionName)
{
try
{
MongoCollection mc = this._db.GetCollection(collectionName);
query = this.InitQuery(query);
//根据指定查询移除数据
mc.Remove(query);
return true;
}
catch (Exception ex)
{
return false;
}
}
///
/// 移除指定的数据
///
/// 移除的数据类型
/// 移除的数据条件
public void Remove(IMongoQuery query)
{
string collectionName = typeof(T).Name;
this.Remove(query, collectionName);
}
///
/// 移除实体里面所有的数据
///
/// 移除的数据类型
public void ReomveAll()
{
string collectionName = typeof(T).Name;
this.Remove(null);
}
///
/// 移除实体里面所有的数据
///
/// 移除的数据类型
/// 指定的集合名称
public void RemoveAll(string collectionName)
{
this.Remove(null);
}
#endregion
#region 创建索引
///
/// 创建索引
///
/// 需要创建索引的实体类型
public void CreateIndex()
{
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.Ascending(property.Name);
}
//创建该属性
mc.CreateIndex(indexKey, IndexOptions.SetUnique(mongoField.Unique));
}
}
}
}
#endregion
#region 获取集合的存储大小
///
/// 获取集合的存储大小
///
/// 该集合对应的实体类
/// 返回一个long型
public long GetDataSize()
{
string collectionName = typeof(T).Name;
return GetDataSize(collectionName);
}
///
/// 获取集合的存储大小
///
/// 该集合对应的名称
/// 返回一个long型
public long GetDataSize(string collectionName)
{
MongoCollection mc = this._db.GetCollection(collectionName);
return mc.GetTotalStorageSize();
}
#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)
{
if (sortBy == null)
{
//默认ObjectId 递增
sortBy = new SortByDocument(OBJECTID_KEY, -1);
}
return sortBy;
}
#endregion
#region 通过mongoGridS保存文件
///
/// 通过mongoGridS保存文件
///
/// 文件二进制流
/// 文件名称
public bool SaveFilesByGridFS(byte[] FileData, string FileName, BsonDocument doc, string FilesType)
{
bool flag = false;
try
{
MongoGridFSSettings fsSetting = new MongoGridFSSettings() { Root = FilesType };
MongoGridFS fs = new MongoGridFS(_db, fsSetting);
//通过Metadata 添加附加信息
MongoGridFSCreateOptions option = new MongoGridFSCreateOptions();
option.UploadDate = DateTime.Now;
//BsonDocument doc = new BsonDocument();
//doc.Add("UserID", 1L);
//doc.Add("GUID", System.Guid.NewGuid());
option.Metadata = doc;
//创建文件,文件并存储数据
using (MongoGridFSStream gfs = fs.Create(FileName, option))
{
gfs.Write(FileData, 0, FileData.Length);
gfs.Close();
}
flag = true;
}
catch (Exception e)
{
flag = false;
}
return flag;
}
#endregion
#region 通过mongoGridS得到图片
///
/// 通过mongoGridS得到图片
///
/// 文件二进制流
/// 文件名称
public byte[] GetFileByGridFS(string ResGuid, string FilesType)
{
byte[] bytes;
try
{
MongoGridFSSettings fsSetting = new MongoGridFSSettings() { Root = FilesType };
MongoGridFS gridfs = new MongoGridFS(_db, fsSetting);
// 定义查询条件
var query = new QueryDocument();
var b = new BsonDocument();
b.Add("metadata.GUID", ResGuid);
query.Add(b);
//得到文件信息
MongoGridFSFileInfo VideoInfo = gridfs.FindOne(query);
if (VideoInfo != null)
{
//读取
using (MongoGridFSStream gridFileStream = VideoInfo.OpenRead())
{
//数组大小
bytes = new byte[gridFileStream.Length];
//存入二进制
gridFileStream.Read(bytes, 0, (int)gridFileStream.Length);
// gridfs.Download(_Stream, query, 1);
}
}
else
{
bytes = null;
}
}
catch (Exception e)
{
bytes = null;
}
return bytes;
}
#endregion
#region 通过ResGuid,删除图片
///
/// 通过ResGuid,删除图片
///
/// 文件二进制流
/// 文件名称
public bool DelFileByGridFS(string ResGuid, string FilesType)
{
bool flag = false;
try
{
MongoGridFSSettings fsSetting = new MongoGridFSSettings() { Root = FilesType };
MongoGridFS gridfs = new MongoGridFS(_db, fsSetting);
// 定义查询条件
var query = new QueryDocument();
var b = new BsonDocument();
b.Add("metadata.GUID", ResGuid);
query.Add(b);
//得到文件信息
MongoGridFSFileInfo ExistImage = gridfs.FindOne(query);
if (ExistImage != null)
{
ExistImage.Delete();
flag = true;
}
else
{
flag = false;
}
}
catch (Exception e)
{
flag = false;
}
return flag;
}
#endregion
}
}