1. 程式人生 > >C#MongoDb 學習筆記

C#MongoDb 學習筆記

本文大部分資料來源於網路資料、書,經過一步步驗證,總結為一篇自己的學習記錄。

簡介: MongoDB是一個基於分散式檔案儲存的資料庫,由C++語言編寫。介於關係資料庫和非關係資料庫之間的產品,是非關係資料庫當中功能最豐富,最像關係資料庫的。他支援的資料結構非常鬆散,類似Json的bson格式,因此可以儲存比較複雜的資料型別。

為什麼使用MongoDB? 我們正在不斷的將我們的物件圖轉換為關係模型,有時候這些轉換很簡單,但在大多數應用中他變得過於複雜。從關係模型檢索資料庫到物件模型時,我們也面臨類似的挑戰。

解壓後得到下面的exe檔案

檔案說明:

Mongo.exe 命令列客戶端工具

Mongod.exe 資料庫服務程式

Mogodump.exe 資料庫備份程式

Mongoexport.exe 資料匯出工具

Mongofiles.exe GridFS工具

Mongoimport.exe 資料匯入工具

Mongorestore 資料恢復工具

Mogos.exe 效能檢測工具

設定MonoDB目錄:

將其解壓到d:\mongodb,exe所在位置為d:\mongodb\bin

設定資料檔案路徑:

在d:\mongodb目錄建立data資料夾,在data資料夾新建db資料夾,log資料夾

啟動MongoDB服務

開啟cmd ,輸入以下命令

d:

cd d:\mongodb\bin

mongod.exe  --dbpath= d:\mongodb\db

2018-02-18T01:31:19.108+0800 I CONTROL  [initandlisten] MongoDB starting : pid=19532 port=27017dbpath=D:\workfloder\2018Study\MongoDB\mongodb-win32-x86_64-v3.4-latest\mongodb-win32-x86_64-3.4.13-13-g6408164\data\db64-bit host=guanzhx

2018-02-18T01:31:19.109+0800 I CONTROL  [initandlisten] targetMinOS: WindowsVista/Windows Server 2008

2018-02-18T01:31:19.109+0800 I CONTROL  [initandlisten] db versionv3.4.13-13-g6408164

2018-02-18T01:31:19.109+0800 I CONTROL  [initandlisten] git version:6408164d14181b8717bdcb462456a90c16020a42

2018-02-18T01:31:19.109+0800 I CONTROL  [initandlisten] allocator: tcmalloc

2018-02-18T01:31:19.109+0800 I CONTROL  [initandlisten] modules: none

2018-02-18T01:31:19.109+0800 I CONTROL  [initandlisten] build environment:

2018-02-18T01:31:19.109+0800 I CONTROL  [initandlisten]     distarch: x86_64

2018-02-18T01:31:19.109+0800 I CONTROL  [initandlisten]     target_arch: x86_64

2018-02-18T01:31:19.109+0800 I CONTROL  [initandlisten] options: { storage: { dbPath:"D:\workfloder\2018Study\MongoDB\mongodb-win32-x86_64-v3.4-latest\mongodb-win32-x86_64-3.4.13-13-g6408164\data\db"} }

2018-02-18T01:31:19.110+0800 I -        [initandlisten] Detected data files inD:\workfloder\2018Study\MongoDB\mongodb-win32-x86_64-v3.4-latest\mongodb-win32-x86_64-3.4.13-13-g6408164\data\dbcreated by the 'wiredTiger' storage engine, so setting the active storageengine to 'wiredTiger'.

2018-02-18T01:31:19.110+0800 I STORAGE  [initandlisten] wiredtiger_open config:create,cache_size=7616M,session_max=20000,eviction=(threads_min=4,threads_max=4),config_base=false,statistics=(fast),log=(enabled=true,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000),checkpoint=(wait=60,log_size=2GB),statistics_log=(wait=0),verbose=(recovery_progress),

2018-02-18T01:31:19.646+0800 I STORAGE  [initandlisten] WiredTiger message [1518888679:645990][19532:140707715244368],txn-recover: Main recovery loop: starting at 2/4224

2018-02-18T01:31:19.786+0800 I STORAGE  [initandlisten] WiredTiger message[1518888679:786143][19532:140707715244368], txn-recover: Recovering log 2through 3

2018-02-18T01:31:19.923+0800 I STORAGE  [initandlisten] WiredTiger message[1518888679:922973][19532:140707715244368], txn-recover: Recovering log 3through 3

2018-02-18T01:31:20.372+0800 I CONTROL  [initandlisten]

2018-02-18T01:31:20.373+0800 I CONTROL  [initandlisten] ** WARNING: Access control isnot enabled for the database.

2018-02-18T01:31:20.375+0800 I CONTROL  [initandlisten] **          Read and write access to data andconfiguration is unrestricted.

2018-02-18T01:31:20.376+0800 I CONTROL  [initandlisten]

2018-02-18T01:31:21.103+0800 I FTDC     [initandlisten] Initializing full-timediagnostic data capture with directory'D:/workfloder/2018Study/MongoDB/mongodb-win32-x86_64-v3.4-latest/mongodb-win32-x86_64-3.4.13-13-g6408164/data/db/diagnostic.data'

2018-02-18T01:31:21.106+0800 I NETWORK  [thread1] waiting for connections on port27017

注意:MongoDB區分大小寫。如果指定了日誌路徑,則在cmd上不會顯示資訊,而是輸入到了日誌檔案中。

如果看到以上資訊,則說明MongoDB服務啟動成功了,紅色字型為啟動服務主機資訊

將MongoDB作為Windows服務隨機啟動

建立好日誌目錄後,cmd命令:

mongod.exe  --dbpath=d:\mongodb\db --logpath d:\mongodb\data\log\mongodb.log–logappend --serviceName guanzhx_MongoDBService --serviceDisplayName guanzhx_MongoDBService-install

解除安裝服務:

mongod.exe --serviceName guanzhx_MongoDBService -remove

接下來開啟客戶端連線服務:

直接開啟bin目錄的mongo.exe

MongoDB shell version v3.4.13-13-g6408164

connecting to: mongodb://127.0.0.1:27017

MongoDB server version: 3.4.13-13-g6408164

連線成功,此時可以輸入命令檢視所有表:

> show dbs

admin 0.000GB

local 0.000GB

此時可以檢視mongodb.log日誌檔案,可以檢視MongoDB服務的執行情況

It looks like you are trying to accessMongoDB over HTTP on the native driver port.

至此,MongoDB服務已經正常運行了。

簡單命令介紹:

引用資料庫: use 表名

查詢資料: 條件:db.表名.findOne({“欄位1”:”值”})  無條件 db.表名.find({})

啟用驗證: --auth=true

思考:

MongoDB服務啟動命令是可以使用配置檔案來統一設定的,但個人在MongoDB使用中常用到的命令不多,製成bat指令碼即可。

將命令合併到bat批命令指令碼啟動MongoDB服務,在測試過程中,因使用的win10家庭版作業系統,時常遇到許可權問題,那麼可以一同用命令來解決:

@echo off

CLS

ECHO.

ECHO ================================

ECHO 嘗試獲取管理員許可權

ECHO ================================

:init

setlocal DisableDelayedExpansion

set "batchPath=%~0"

for %%k in (%0) do set batchName=%%~nk

set"vbsGetPrivileges=%temp%\OEgetPriv_%batchName%.vbs"

setlocal EnableDelayedExpansion

:checkPrivileges

NET FILE 1>NUL 2>NUL

if '%errorlevel%' == '0' ( gotogotPrivileges ) else ( goto getPrivileges )

:getPrivileges

if '%1'=='ELEV' (echo ELEV & shift /1& goto gotPrivileges)

ECHO.

ECHO ********************************

ECHO 請求 UAC 許可權批准……

ECHO ********************************

ECHO Set UAC =CreateObject^("Shell.Application"^) >"%vbsGetPrivileges%"

ECHO args = "ELEV " >>"%vbsGetPrivileges%"

ECHO For Each strArg in WScript.Arguments>> "%vbsGetPrivileges%"

ECHO args = args ^& strArg ^&" "  >>"%vbsGetPrivileges%"

ECHO Next >>"%vbsGetPrivileges%"

ECHO UAC.ShellExecute"!batchPath!", args, "", "runas", 1 >>"%vbsGetPrivileges%"

"%SystemRoot%\System32\WScript.exe""%vbsGetPrivileges%" %*

exit /B

:gotPrivileges

setlocal & pushd .

cd /d %~dp0

if '%1'=='ELEV' (del"%vbsGetPrivileges%" 1>nul 2>nul  & shift /1)

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

::    以下為需要執行的批處理檔案程式碼     ::

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

rem 本行以下可修改為你需要的bat命令(從上面三行冒號開始到下面都可刪改)

ECHO 正在啟動服務...

SET VERSION=guanzhx

SET CURRENTPATH=%~dp0

SETLOGPATH=%CURRENTPATH%\data\log\mongodb.log

SET DBPATH=%CURRENTPATH%\data\db

cd bin

mongod.exe --logpath %LOGPATH% --logappend--dbpath %DBPATH% --serviceName %VERSION%_MongoDBService --serviceDisplayName%VERSION%_MongoDBService -install

net start %VERSION%_MongoDBService

pause

================================

嘗試獲取管理員許可權

================================

正在啟動服務...

guanzhx_MongoDBService 服務正在啟動 ..

guanzhx_MongoDBService 服務已經啟動成功。

請按任意鍵繼續. . .

當然解除安裝服務也類似。

在.NET中使用MongoDB

視覺化工具Robomongo

視覺化工具(官方)

下載GitHub原始碼後進行編譯,可以獲得MongoDB.dll,引用專案即可。

在原始碼中已經包含了使用示例,研究後簡化出常用的方法。

MongoDBHelper(基礎方法全部封裝完成):

using MongoDB;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MongoDb.Utils
{
    public static class MongDBHelper
    {
        private static readonly string _connectionString = "Server=127.0.0.1";

        private static readonly string _dbName = "MyNorthwind";

        // 摘記: safemode:僅在寫入資料庫時才有用 
        // 為了提高速度,如果安全模式關閉並且寫入操作失敗,則驅動程式不會等待,.NET不會引發異常
        // 將safemode設定為true將強制驅動程式等待成功確認,並且如果發生錯誤就會引發異常
        // 使用安全模式處理您關心的資料
        // MongoDB預設行為是關閉


        /// <summary>
        /// 增加一條記錄
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity">實體</param>
        /// <param name="safeMode">安全模式</param>
        public static void Insert<T>(T entity, bool safeMode = false) where T : class
        {
            using (Mongo mongo = new Mongo(_connectionString))
            {
                mongo.Connect();
                IMongoDatabase friends = mongo.GetDatabase(_dbName);
                // 兩種方法: 呼叫  mh.Insert("類名稱", 例項物件);
                IMongoCollection<T> categories = friends.GetCollection<T>();
                //  呼叫  mh.Insert<Customer>(例項物件);
                //IMongoCollection<T> categories = friends.GetCollection<T>("collectionName");
                categories.Insert(entity, safeMode);
                mongo.Disconnect();
            }
        }
        /// <summary>
        /// 增加多條記錄
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity">實體</param>
        /// <param name="safeMode">安全模式</param>
        public static void Insert<T>(IEnumerable<T> entity, bool safeMode = false) where T : class
        {
            using (Mongo mongo = new Mongo(_connectionString))
            {
                mongo.Connect();
                IMongoDatabase friends = mongo.GetDatabase(_dbName);
                // 兩種方法: 呼叫  mh.Insert("類名稱", 例項物件);
                IMongoCollection<T> categories = friends.GetCollection<T>();
                //  呼叫  mh.Insert<Customer>(例項物件);
                //IMongoCollection<T> categories = friends.GetCollection<T>("collectionName");
                categories.Insert(entity, safeMode);
                mongo.Disconnect();
            }
        }
        /// <summary>
        /// 更新一條記錄
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="query"></param>
        /// <param name="collectionName"></param>
        /// <param name="safeMode">安全模式</param>
        public static void Update<T>(T entity, Document query,string collectionName,bool safeMode=false) where T : class
        {
            using (Mongo mongo = new Mongo(_connectionString))
            {
                mongo.Connect();
                IMongoDatabase db = mongo.GetDatabase(_dbName);
                IMongoCollection<Document> collection = db.GetCollection<Document>(collectionName);
                Document record = collection.FindOne(query);
                var selector = new Document { { "_id", record["_id"] } };
                // 更新物件
                collection.Update(entity, selector, safeMode);
            }
        }
        /// <summary>
        /// 獲取一條資料
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="collectionName"></param>
        /// <param name="query"></param>
        /// <returns></returns>
        public static T GetOne<T>(Document query) where T : class
        {
            T result = default(T);
            using (Mongo mongo = new Mongo(_connectionString))
            {
                mongo.Connect();
                IMongoDatabase friends = mongo.GetDatabase(_dbName);
                IMongoCollection<T> categories = friends.GetCollection<T>();
                result = categories.FindOne(query);
                mongo.Disconnect();
            }
            return result;
        }
        /// <summary>
        /// 獲取一個集合下所有資料
        /// </summary>
        /// <returns></returns>
        public static List<T> GetAll<T>() where T : class
        {
            List<T> result = new List<T>();
            using (Mongo mongo = new Mongo(_connectionString))
            {
                mongo.Connect();
                IMongoDatabase friends = mongo.GetDatabase(_dbName);
                IMongoCollection<T> categories = friends.GetCollection<T>();
                foreach (T entity in categories.FindAll().Documents)
                {
                    result.Add(entity);
                }
                mongo.Disconnect();

            }
            return result;
        }
        /// <summary>
        /// 獲取列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="query"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public static List<T> GetList<T>(Document selector, int pageIndex, int pageSize) where T : class
        {
            List<T> result = new List<T>();
            using (Mongo mongo = new Mongo(_connectionString))
            {
                mongo.Connect();
                IMongoDatabase friends = mongo.GetDatabase(_dbName);
                IMongoCollection<T> categories = friends.GetCollection<T>();
                // 使用這種語法不支援: .Sort(sort).Skip((cp - 1) * mp).Limit(mp)
                foreach (T entity in categories.Find(selector, pageSize, (pageIndex - 1) * pageSize).Documents)
                {
                    result.Add(entity);
                }
                mongo.Disconnect();
                //linq的一種寫法
                //collection.FindOne(x => x.CustomerID == searchWord || x.CustomerName == searchWord || x.ContactName == searchWord);
            }
            return result;
        }
        /// <summary>
        /// 刪除資料
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="collectionName"></param>
        /// <param name="query"></param>
        public static void Delete<T>(string collectionName,Document query) where T : class
        {
            using (Mongo mongo = new Mongo(_connectionString))
            {
                mongo.Connect();
                IMongoDatabase friends = mongo.GetDatabase(_dbName);
                IMongoCollection<T> categories = friends.GetCollection<T>(collectionName);
                categories.Remove(query, true);
                mongo.Disconnect();
            }
        }
    }
}

呼叫:

using MongoDb.Utils;
using MongoDB;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MongoDb.Consoles
{
    class Program
    {

        static void Main(string[] args)
        {

            
            // insert 

            Customer ct = new Customer();
            ct.CustomerID = Guid.NewGuid().ToString();
            ct.CustomerName = "guanzhx";
            ct.ContactName = "帥哥";
            ct.Address = "地球";
            ct.PostalCode = "100000";
            ct.Tel = "110";
            MongDBHelper.Insert<Customer>(ct,true);

            // update 
            Document dc = new Document { { "CustomerName", "guanzhx" } };
            MongDBHelper.Update<Customer>(ct, dc, "Customer");

            // 查詢一條記錄
            Console.WriteLine("查詢單條記錄:"+MongDBHelper.GetOne<Customer>(dc).ContactName);
            // 查詢所有記錄
            foreach (Customer item in MongDBHelper.GetAll<Customer>())
            {
                Console.WriteLine("迴圈輸出所有記錄:"+ item.ContactName);
            }
            // 查詢條件集合
            Document searchWord = new Document { { "ContactName", "帥哥" } }; //"_id" : "5f0c841e-57f0-4189-8e9e-ff9edf21a7fc",
            foreach (Customer item in MongDBHelper.GetList<Customer>(searchWord, 1, 10))
            {
                Console.WriteLine("迴圈輸出條件記錄:" + item.ContactName);
            }
            // 刪除
            MongDBHelper.Delete<Document>("Customer", searchWord);
            Console.WriteLine("刪除記錄:條件:ContactName=帥哥:");

            Console.ReadLine();
        }
    }
}