Mongodb使用基礎-Mongodb.Driver操作MongoDB


上一篇博客主要介紹了MongoDB和它的的使用場景,這篇文章主要介紹一下如何用C#如何借助官方的Mongodb.Driver操作MongoDB

1.NuGet引入Mongodb.Dirver

安裝后項目中會新增如下dll

MongoDB.Driver.dll:顧名思義,驅動程序

MongoDB.Bson.dll:序列化、Json相關

 

2.初始化集合,子類需重寫集合名

        #region 構造函數
        /// <summary>
        /// 集合
        /// </summary>
        public string _collName { get; set; }
        public MongoBaseRepository(string collName)
        {
            this._collName = collName;
        }
        #endregion
View Code

3..初始化鏈接和數據庫

#region 連接配置
        /// <summary>
        /// 鏈接
        /// </summary>
        private static readonly string conneStr = "mongodb://127.0.0.1:27017";
        /// <summary>
        /// 數據庫
        /// </summary>
        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<T> GetClient<T>() where T : class, new()
        {
            return _database.GetCollection<T>(_collName);
        }
        #endregion
View Code

4.操作

Add:

 #region +Add 添加一條數據
        /// <summary>
        /// 添加一條數據
        /// </summary>
        /// <param name="t">添加的實體</param>
        /// <param name="host">mongodb連接信息</param>
        /// <returns></returns>
        public int Add<T>(T t) where T : class, new()
        {
            try
            {
                var client = _database.GetCollection<T>(_collName);
                client.InsertOne(t);
                return 1;
            }
            catch (Exception ex)
            {
                return 0;
            }
        }
        #endregion

        #region +AddAsync 異步添加一條數據
        /// <summary>
        /// 異步添加一條數據
        /// </summary>
        /// <param name="t">添加的實體</param>
        /// <param name="host">mongodb連接信息</param>
        /// <returns></returns>
        public async Task<int> AddAsync<T>(T t) where T : class, new()
        {
            try
            {
                var client = _database.GetCollection<T>(_collName);
                await client.InsertOneAsync(t);
                return 1;
            }
            catch
            {
                return 0;
            }
        }
        #endregion

        #region +InsertMany 批量插入
        /// <summary>
        /// 批量插入
        /// </summary>
        /// <param name="host">mongodb連接信息</param>
        /// <param name="t">實體集合</param>
        /// <returns></returns>
        public int InsertMany<T>(List<T> t) where T : class, new()
        {
            try
            {
                var client = _database.GetCollection<T>(_collName);
                client.InsertMany(t);
                return 1;
            }
            catch (Exception ex)
            {
                return 0;
            }
        }
        #endregion

        #region +InsertManyAsync 異步批量插入
        /// <summary>
        /// 異步批量插入
        /// </summary>
        /// <param name="host">mongodb連接信息</param>
        /// <param name="t">實體集合</param>
        /// <returns></returns>
        public async Task<int> InsertManyAsync<T>(List<T> t) where T : class, new()
        {
            try
            {
                var client = _database.GetCollection<T>(_collName);
                await client.InsertManyAsync(t);
                return 1;
            }
            catch
            {
                return 0;
            }
        }
        #endregion
View Code

Modify:

  #region +Update 修改一條數據
        /// <summary>
        /// 修改一條數據
        /// </summary>
        /// <param name="t">添加的實體</param>
        /// <param name="host">mongodb連接信息</param>
        /// <returns></returns>
        public UpdateResult Update<T>(T t, string id, bool isObjectId = true) where T : class, new()
        {
            try
            {
                var client = _database.GetCollection<T>(_collName);
                //修改條件
                FilterDefinition<T> filter;
                if (isObjectId)
                {
                    filter = Builders<T>.Filter.Eq("_id", new ObjectId(id));
                }
                else
                {
                    filter = Builders<T>.Filter.Eq("_id", id);
                }
                //要修改的字段
                var list = new List<UpdateDefinition<T>>();
                foreach (var item in t.GetType().GetProperties())
                {
                    if (item.Name.ToLower() == "id") continue;
                    list.Add(Builders<T>.Update.Set(item.Name, item.GetValue(t)));
                }
                var updatefilter = Builders<T>.Update.Combine(list);
                return client.UpdateOne(filter, updatefilter);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region +UpdateAsync 異步修改一條數據
        /// <summary>
        /// 異步修改一條數據
        /// </summary>
        /// <param name="t">添加的實體</param>
        /// <param name="host">mongodb連接信息</param>
        /// <returns></returns>
        public async Task<UpdateResult> UpdateAsync<T>(T t, string id, bool isObjectId) where T : class, new()
        {
            try
            {
                var client = _database.GetCollection<T>(_collName);
                //修改條件
                FilterDefinition<T> filter;
                if (isObjectId)
                {
                    filter = Builders<T>.Filter.Eq("_id", new ObjectId(id));
                }
                else
                {
                    filter = Builders<T>.Filter.Eq("_id", id);
                }
                //要修改的字段
                var list = new List<UpdateDefinition<T>>();
                foreach (var item in t.GetType().GetProperties())
                {
                    if (item.Name.ToLower() == "id") continue;
                    list.Add(Builders<T>.Update.Set(item.Name, item.GetValue(t)));
                }
                var updatefilter = Builders<T>.Update.Combine(list);
                return await client.UpdateOneAsync(filter, updatefilter);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region +UpdateManay 批量修改數據
        /// <summary>
        /// 批量修改數據
        /// </summary>
        /// <param name="dic">要修改的字段</param>
        /// <param name="host">mongodb連接信息</param>
        /// <param name="filter">修改條件</param>
        /// <returns></returns>
        public UpdateResult UpdateManay<T>(Dictionary<string, string> dic, FilterDefinition<T> filter) where T : class, new()
        {
            try
            {
                var client = _database.GetCollection<T>(_collName);
                T t = new T();
                //要修改的字段
                var list = new List<UpdateDefinition<T>>();
                foreach (var item in t.GetType().GetProperties())
                {
                    if (!dic.ContainsKey(item.Name)) continue;
                    var value = dic[item.Name];
                    list.Add(Builders<T>.Update.Set(item.Name, value));
                }
                var updatefilter = Builders<T>.Update.Combine(list);
                return client.UpdateMany(filter, updatefilter);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region +UpdateManayAsync 異步批量修改數據
        /// <summary>
        /// 異步批量修改數據
        /// </summary>
        /// <param name="dic">要修改的字段</param>
        /// <param name="host">mongodb連接信息</param>
        /// <param name="filter">修改條件</param>
        /// <returns></returns>
        public async Task<UpdateResult> UpdateManayAsync<T>(Dictionary<string, string> dic, FilterDefinition<T> filter) where T : class, new()
        {
            try
            {
                var client = _database.GetCollection<T>(_collName);
                T t = new T();
                //要修改的字段
                var list = new List<UpdateDefinition<T>>();
                foreach (var item in t.GetType().GetProperties())
                {
                    if (!dic.ContainsKey(item.Name)) continue;
                    var value = dic[item.Name];
                    list.Add(Builders<T>.Update.Set(item.Name, value));
                }
                var updatefilter = Builders<T>.Update.Combine(list);
                return await client.UpdateManyAsync(filter, updatefilter);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion
View Code

Remove:

 #region Delete 刪除一條數據
        /// <summary>
        /// 刪除一條數據
        /// </summary>
        /// <param name="host">mongodb連接信息</param>
        /// <param name="id">objectId</param>
        /// <returns></returns>
        public DeleteResult Delete<T>(string id, bool isObjectId = true) where T : class, new()
        {
            try
            {
                var client = _database.GetCollection<T>(_collName);
                FilterDefinition<T> filter;
                if (isObjectId)
                {
                    filter = Builders<T>.Filter.Eq("_id", new ObjectId(id));
                }
                else
                {
                    filter = Builders<T>.Filter.Eq("_id", id);
                }
                return client.DeleteOne(filter);
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }
        #endregion

        #region DeleteAsync 異步刪除一條數據
        /// <summary>
        /// 異步刪除一條數據
        /// </summary>
        /// <param name="host">mongodb連接信息</param>
        /// <param name="id">objectId</param>
        /// <returns></returns>
        public async Task<DeleteResult> DeleteAsync<T>(string id, bool isObjectId = true) where T : class, new()
        {
            try
            {
                var client = _database.GetCollection<T>(_collName);
                //修改條件
                FilterDefinition<T> filter;
                if (isObjectId)
                {
                    filter = Builders<T>.Filter.Eq("_id", new ObjectId(id));
                }
                else
                {
                    filter = Builders<T>.Filter.Eq("_id", id);
                }
                return await client.DeleteOneAsync(filter);
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }
        #endregion

        #region DeleteMany 刪除多條數據
        /// <summary>
        /// 刪除一條數據
        /// </summary>
        /// <param name="host">mongodb連接信息</param>
        /// <param name="filter">刪除的條件</param>
        /// <returns></returns>
        public DeleteResult DeleteMany<T>(FilterDefinition<T> filter) where T : class, new()
        {
            try
            {
                var client = _database.GetCollection<T>(_collName);
                return client.DeleteMany(filter);
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }
        #endregion

        #region DeleteManyAsync 異步刪除多條數據
        /// <summary>
        /// 異步刪除多條數據
        /// </summary>
        /// <param name="host">mongodb連接信息</param>
        /// <param name="filter">刪除的條件</param>
        /// <returns></returns>
        public async Task<DeleteResult> DeleteManyAsync<T>(FilterDefinition<T> filter) where T : class, new()
        {
            try
            {
                var client = _database.GetCollection<T>(_collName);
                return await client.DeleteManyAsync(filter);
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }
        #endregion
View Code

Find:

 #region FindOne 根據id查詢一條數據
        /// <summary>
        /// 根據id查詢一條數據
        /// </summary>
        /// <param name="host">mongodb連接信息</param>
        /// <param name="id">objectid</param>
        /// <param name="field">要查詢的字段,不寫時查詢全部</param>
        /// <returns></returns>
        public T FindOne<T>(string id, bool isObjectId = true, string[] field = null) where T : class, new()
        {
            try
            {
                var client = _database.GetCollection<T>(_collName);
                FilterDefinition<T> filter;
                if (isObjectId)
                {
                    filter = Builders<T>.Filter.Eq("_id", new ObjectId(id));
                }
                else
                {
                    filter = Builders<T>.Filter.Eq("_id", id);
                }
                //不指定查詢字段
                if (field == null || field.Length == 0)
                {
                    return client.Find(filter).FirstOrDefault<T>();
                }

                //制定查詢字段
                var fieldList = new List<ProjectionDefinition<T>>();
                for (int i = 0; i < field.Length; i++)
                {
                    fieldList.Add(Builders<T>.Projection.Include(field[i].ToString()));
                }
                var projection = Builders<T>.Projection.Combine(fieldList);
                fieldList?.Clear();
                return client.Find(filter).Project<T>(projection).FirstOrDefault<T>();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region FindOneAsync 異步根據id查詢一條數據
        /// <summary>
        /// 異步根據id查詢一條數據
        /// </summary>
        /// <param name="host">mongodb連接信息</param>
        /// <param name="id">objectid</param>
        /// <returns></returns>
        public async Task<T> FindOneAsync<T>(string id, bool isObjectId = true, string[] field = null) where T : class, new()
        {
            try
            {
                var client = _database.GetCollection<T>(_collName);
                FilterDefinition<T> filter;
                if (isObjectId)
                {
                    filter = Builders<T>.Filter.Eq("_id", new ObjectId(id));
                }
                else
                {
                    filter = Builders<T>.Filter.Eq("_id", id);
                }

                //不指定查詢字段
                if (field == null || field.Length == 0)
                {
                    return await client.Find(filter).FirstOrDefaultAsync();
                }

                //制定查詢字段
                var fieldList = new List<ProjectionDefinition<T>>();
                for (int i = 0; i < field.Length; i++)
                {
                    fieldList.Add(Builders<T>.Projection.Include(field[i].ToString()));
                }
                var projection = Builders<T>.Projection.Combine(fieldList);
                fieldList?.Clear();
                return await client.Find(filter).Project<T>(projection).FirstOrDefaultAsync();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region FindList 查詢集合
        /// <summary>
        /// 查詢集合
        /// </summary>
        /// <param name="host">mongodb連接信息</param>
        /// <param name="filter">查詢條件</param>
        /// <param name="field">要查詢的字段,不寫時查詢全部</param>
        /// <param name="sort">要排序的字段</param>
        /// <returns></returns>
        public List<T> FindList<T>(FilterDefinition<T> filter, string[] field = null, SortDefinition<T> sort = null) where T : class, new()
        {
            try
            {
                var client = _database.GetCollection<T>(_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<ProjectionDefinition<T>>();
                for (int i = 0; i < field.Length; i++)
                {
                    fieldList.Add(Builders<T>.Projection.Include(field[i].ToString()));
                }
                var projection = Builders<T>.Projection.Combine(fieldList);
                fieldList?.Clear();
                if (sort == null) return client.Find(filter).Project<T>(projection).ToList();
                //排序查詢
                return client.Find(filter).Sort(sort).Project<T>(projection).ToList();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region FindListAsync 異步查詢集合
        /// <summary>
        /// 異步查詢集合
        /// </summary>
        /// <param name="host">mongodb連接信息</param>
        /// <param name="filter">查詢條件</param>
        /// <param name="field">要查詢的字段,不寫時查詢全部</param>
        /// <param name="sort">要排序的字段</param>
        /// <returns></returns>
        public async Task<List<T>> FindListAsync<T>(FilterDefinition<T> filter, string[] field = null, SortDefinition<T> sort = null) where T : class, new()
        {
            try
            {
                var client = _database.GetCollection<T>(_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<ProjectionDefinition<T>>();
                for (int i = 0; i < field.Length; i++)
                {
                    fieldList.Add(Builders<T>.Projection.Include(field[i].ToString()));
                }
                var projection = Builders<T>.Projection.Combine(fieldList);
                fieldList?.Clear();
                if (sort == null) return await client.Find(filter).Project<T>(projection).ToListAsync();
                //排序查詢
                return await client.Find(filter).Sort(sort).Project<T>(projection).ToListAsync();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region FindListByPage 分頁查詢集合
        /// <summary>
        /// 分頁查詢集合
        /// </summary>
        /// <param name="host">mongodb連接信息</param>
        /// <param name="filter">查詢條件</param>
        /// <param name="pageIndex">當前頁</param>
        /// <param name="pageSize">頁容量</param>
        /// <param name="count">總條數</param>
        /// <param name="field">要查詢的字段,不寫時查詢全部</param>
        /// <param name="sort">要排序的字段</param>
        /// <returns></returns>
        public List<T> FindListByPage<T>(FilterDefinition<T> filter, int pageIndex, int pageSize, out long count, string[] field = null, SortDefinition<T> sort = null) where T : class, new()
        {
            try
            {
                var client = _database.GetCollection<T>(_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<ProjectionDefinition<T>>();
                for (int i = 0; i < field.Length; i++)
                {
                    fieldList.Add(Builders<T>.Projection.Include(field[i].ToString()));
                }
                var projection = Builders<T>.Projection.Combine(fieldList);
                fieldList?.Clear();

                //不排序
                if (sort == null) return client.Find(filter).Project<T>(projection).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToList();

                //排序查詢
                return client.Find(filter).Sort(sort).Project<T>(projection).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToList();

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region FindListByPageAsync 異步分頁查詢集合
        /// <summary>
        /// 異步分頁查詢集合
        /// </summary>
        /// <param name="host">mongodb連接信息</param>
        /// <param name="filter">查詢條件</param>
        /// <param name="pageIndex">當前頁</param>
        /// <param name="pageSize">頁容量</param>
        /// <param name="field">要查詢的字段,不寫時查詢全部</param>
        /// <param name="sort">要排序的字段</param>
        /// <returns></returns>
        public async Task<List<T>> FindListByPageAsync<T>(FilterDefinition<T> filter, int pageIndex, int pageSize, string[] field = null, SortDefinition<T> sort = null) where T : class, new()
        {
            try
            {
                var client = _database.GetCollection<T>(_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<ProjectionDefinition<T>>();
                for (int i = 0; i < field.Length; i++)
                {
                    fieldList.Add(Builders<T>.Projection.Include(field[i].ToString()));
                }
                var projection = Builders<T>.Projection.Combine(fieldList);
                fieldList?.Clear();

                //不排序
                if (sort == null) return await client.Find(filter).Project<T>(projection).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync();

                //排序查詢
                return await client.Find(filter).Sort(sort).Project<T>(projection).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync();

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion
View Code

Count:

        #region Count 根據條件獲取總數
        /// <summary>
        /// 根據條件獲取總數
        /// </summary>
        /// <param name="host">mongodb連接信息</param>
        /// <param name="filter">條件</param>
        /// <returns></returns>
        public long Count<T>(FilterDefinition<T> filter) where T : class, new()
        {
            try
            {
                var client = _database.GetCollection<T>(_collName);
                return client.CountDocuments(filter);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region CountAsync 異步根據條件獲取總數
        /// <summary>
        /// 異步根據條件獲取總數
        /// </summary>
        /// <param name="host">mongodb連接信息</param>
        /// <param name="filter">條件</param>
        /// <returns></returns>
        public async Task<long> CountAsync<T>( FilterDefinition<T> filter) where T : class, new()
        {
            try
            {
                var client = _database.GetCollection<T>(_collName);
                return await client.CountDocumentsAsync(filter);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion
View Code

查詢實例:

        public async Task<IList<Messages>> MyMessage(BaseCondition condition)
        {
            //根據時間排序
            var sort = Builders<Messages>.Sort.Ascending("State");
            var list = new List<FilterDefinition<Messages>>();
            list.Add(Builders<Messages>.Filter.Eq("ReciveCode","admin"));
            //>開始時間 <結束時間
            if (!string.IsNullOrEmpty(condition.startTime) && !string.IsNullOrEmpty(condition.endTime))
            {
                list.Add(Builders<Messages>.Filter.Gte("CreateDate", condition.startTime));
                list.Add(Builders<Messages>.Filter.Lte("CreateDate", condition.endTime));
            }
            //Or條件
            if (!string.IsNullOrEmpty(condition.SerachCondition))
            {
                var list_or = new List<FilterDefinition<Messages>>();
                list_or.Add(Builders<Messages>.Filter.Regex("Title", condition.SerachCondition));
                list_or.Add(Builders<Messages>.Filter.Regex("MContent", condition.SerachCondition));
                list_or.Add(Builders<Messages>.Filter.Regex("SendCode", condition.SerachCondition));
                list.Add(Builders<Messages>.Filter.Or(list_or));
            }
            var filter = Builders<Messages>.Filter.And(list);
            var result = await base.FindListAsync<Messages>(filter, null, sort);
            return result;
        }
View Code

時間格式需要序列化,如下

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”的插入方式

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM