MongoDB數(shù)據(jù)庫(kù)介紹并用.NET?Core對(duì)其進(jìn)行編碼
淺入 MongoDB
MonogoDB 是什么
MongoDB 是 NoSQL 型數(shù)據(jù)庫(kù),主要特征是存儲(chǔ)結(jié)構(gòu)化數(shù)據(jù),MongoDB 是基于分布式文件存儲(chǔ)的開源數(shù)據(jù)庫(kù)系統(tǒng)。
結(jié)構(gòu)化數(shù)據(jù)
以往我們使用 Mysql、SqlServer 等數(shù)據(jù)庫(kù),數(shù)據(jù)都是一條條的。MongoDB 的結(jié)構(gòu)化數(shù)據(jù)正是區(qū)別于這種列-行式的數(shù)據(jù)。
結(jié)構(gòu)化數(shù)據(jù)具有層級(jí)關(guān)系:
例如:
{ name: "MongoDB", type: "database", count: 1, info: { x: 203, y: 102 } }
MongoDB 與關(guān)系型數(shù)據(jù)庫(kù)
由于 MongoDB 中,沒(méi)有表、行、列,因此初學(xué) MongoDB 時(shí)可能會(huì)有困擾,這里給出一些 MongoDB 與 普通SQL數(shù)據(jù)庫(kù)對(duì)應(yīng)的術(shù)語(yǔ)。
SQL術(shù)語(yǔ)/概念 | MongoDB術(shù)語(yǔ)/概念 | 解釋/說(shuō)明 |
---|---|---|
database | database | 數(shù)據(jù)庫(kù) |
table | collection | 數(shù)據(jù)庫(kù)表/集合 |
row | document | 數(shù)據(jù)記錄行/文檔 |
column | field | 數(shù)據(jù)字段/域 |
index | index | 索引 |
table joins | 非關(guān)系型數(shù)據(jù)庫(kù),表與表之間沒(méi)關(guān)系 | |
primary key | primary key | 主鍵,MongoDB自動(dòng)將_id字段設(shè)置為主鍵 |
資料來(lái)源:https://www.runoob.com/mongodb/mongodb-databases-documents-collections.html
MongoDB 入門命令
使用 mongo 進(jìn)入 MongoDB shell 后,可使用命令(相當(dāng)于SQL)執(zhí)行操作。
注: MongoDB 中,有一個(gè)自動(dòng)的 _id 字段,此字段 MongoDB 自動(dòng)設(shè)置為主鍵并自動(dòng)生成值。
顯示所有數(shù)據(jù)庫(kù)(包含系統(tǒng)數(shù)據(jù)庫(kù)):
show dbs
當(dāng)前正在操作的數(shù)據(jù)庫(kù)或集合:
db
連接到指定數(shù)據(jù)庫(kù):
use {數(shù)據(jù)庫(kù)名稱}
顯示所有集合:
show collections # 或 show tables
查看集合中的所有文檔:
# MyCollection 是集合名稱 db.getCollection("MyCollection").find() db.getCollection("MyCollection").find().limit(1000).skip(0)
可能你不信,筆者百度了很久,第一頁(yè)沒(méi)找到一篇合適的友好的 "mongoDB 查看集合中的所有文檔",特別是 CSDN 的垃圾文真的多。建議別瞎折騰了,去下一個(gè) Navicat Premium,操作的時(shí)候,底部會(huì)提示所用的命令。
另外 MongoDB 有很多實(shí)用工具:https://docs.mongodb.com/tools/
文檔
MongoDB 中的文檔(Document)即關(guān)系型數(shù)據(jù)庫(kù)中的一條記錄(row)、一行數(shù)據(jù)。
但, MongoDB 中,一個(gè)集合(Collection-Table)中,是不需要具有相同字段的。例如:
A 文檔:
{ name: "MongoDB", type: "database", count: 1, info: { x: 203, y: 102 } }
B 文檔:
{ name: "MongoDB", typeName: "database", dataCount: 1, dataInfo: { m: 203, n: 102 } }
.NET Core 示例
我們從一個(gè)基礎(chǔ)模板開始。
創(chuàng)建一個(gè)控制臺(tái)程序,打開 Nuget 搜索并安裝 MongoDB.Driver
。
var client = new MongoClient("mongodb://{MongoDB}:27017"); IMongoDatabase database = client.GetDatabase("Test");
集合
可以通過(guò) CreateCollection()
或 CreateCollectionAsync()
創(chuàng)建一個(gè)集合,跟普通數(shù)據(jù)庫(kù)不同的是,創(chuàng)建集合時(shí)是不需要指定結(jié)構(gòu)的,只需要指定名稱即可:
await database.CreateCollectionAsync("Test");
獲取集合
GetCollection()
函數(shù)可以讓我們獲取到集合,如果集合不存在,則會(huì)自動(dòng)創(chuàng)建。
IMongoCollection<TDocument> GetCollection<TDocument>()
由于同一個(gè)集合可以有不同字段和字段類型的文檔,因此幾個(gè)文檔如果有所差別,是很難統(tǒng)一起來(lái)的,例如:
(N/A) 代表此文檔沒(méi)有這個(gè)字段;如果一個(gè)文檔有 10 個(gè)字段,另一個(gè)文檔有 8 個(gè)字段,但是兩者的字段完全不同時(shí),要合并起來(lái)來(lái),就有 18 個(gè)字段了。很明顯,不應(yīng)該匯集在一起,而是應(yīng)該使用強(qiáng)類型對(duì)其 ”歸檔“ 。
創(chuàng)建兩個(gè)類,分別為 Test1,Test2,其內(nèi)容如下:
public class Test1 { public string Name { get; set; } } public class Test2 { public string DataType { get; set; } }
以兩種文檔類型獲取集合:
var collection1 = database.GetCollection<Test1>("Test"); var collection2 = database.GetCollection<Test2>("Test");
這個(gè)獲取集合的意思是,獲取此集合中這類格式的文檔的操作能力。
往集合中插入數(shù)據(jù):
collection1.InsertOne(new Test1 { Name = "Test1" }); collection2.InsertOne(new Test2 { DataType = "Test2" }); // await collection.InsertOneAsync(object);
啟動(dòng),查看結(jié)果。
InsertMany()
可以插入批量數(shù)據(jù):
Test1[] datas = new Test1[] { new Test1 { Name = "Test1" } }; collection1.InsertMany(datas);
統(tǒng)計(jì)數(shù)量
獲取集合中所有的文檔數(shù):
collection1.CountDocuments(new BsonDocument()) // await collection1.CountDocumentsAsync(new BsonDocument());
任意一個(gè)文檔集合對(duì)象,使用 CountDocuments(new BsonDocument())
都是獲得此集合的所有文檔數(shù),而不是此類型的文檔數(shù)。例如:
var collection1 = database.GetCollection<Test1>("Test"); collection1.CountDocuments(new BsonDocument())
獲取的并不是 Test1 類型的文檔數(shù)量,而是整個(gè)集合所有文檔的數(shù)量。
原因是,CountDocuments()
是一個(gè)過(guò)濾器函數(shù),可以使用指定條件來(lái)篩選符合條件的文檔的數(shù)量。指定條件后面會(huì)介紹。
查詢
MongoDB 的查詢并不像 LInq 中的表達(dá)式,基礎(chǔ)了 IEnumerable
或 IEnumerable<T>
接口,因此驅(qū)動(dòng)沒(méi)有 Where
、Select
這種表達(dá)式的查詢方法。
Find()
函數(shù)是查詢函數(shù),里面可以添加豐富的表達(dá)式,來(lái)篩選文檔,當(dāng)數(shù)據(jù)加載到本地內(nèi)存后,即可使用豐富的表達(dá)式。
BsonDocument
是一個(gè)類型,代表了要查詢的文檔篩選條件,如果 BsonDocument
對(duì)象沒(méi)有添加任何屬性,則代碼沒(méi)有篩選參數(shù),則默認(rèn)所有文檔都符號(hào)條件。
我們把 Test1 和 Test2 類型,都加上一個(gè)屬性:
public ObjectId _id { get; set; }
不然會(huì)報(bào)格式化錯(cuò)誤:System.FormatException
如何序列化文檔
document
是文檔對(duì)象, JsonSerializer 是 System.Text.Json 的靜態(tài)類。
Console.WriteLine(JsonSerializer.Serialize(document));
查詢第一條記錄
var document = collection1.Find(new BsonDocument()).FirstOrDefault();
不加條件可能導(dǎo)致的問(wèn)題
以下代碼會(huì)導(dǎo)致程序報(bào)錯(cuò):
var documents = await collection1.Find(new BsonDocument()).ToListAsync(); foreach(var item in documents) { Console.WriteLine(JsonSerializer.Serialize(item)); }
因?yàn)?nbsp;collection1
是標(biāo)記為 Test1
的文檔集合;但是 .Find(new BsonDocument())
是查詢集合中的所有文檔,因此獲取到 Test2。
但是 Test2 是不能轉(zhuǎn)為 Test1 的,因此,會(huì)導(dǎo)致程序報(bào)錯(cuò)。
查看所有文檔
var documents = collection1.Find(new BsonDocument()).ToList(); var documents = await collection1.Find(new BsonDocument()).ToListAsync();
前面已經(jīng)說(shuō)過(guò),如果集合中存在其它格式的文檔,獲取全部文檔時(shí),因?yàn)?Test2 跟 Test1 沒(méi)任何關(guān)系,會(huì)導(dǎo)致 MongoDB.Driver
報(bào)錯(cuò)。
如果文檔數(shù)量比較大,要使用異步的 ForEachAsync()
查詢,其原理是 回調(diào)。
List<Test1> tests = new List<Test1>(); Action<Test1> action = item => { tests.Add(item); Console.WriteLine(JsonSerializer.Serialize(item)); }; await collection1.Find(new BsonDocument()).ForEachAsync(action);
查詢結(jié)束
使用 Find()
以及后續(xù)函數(shù)查詢后,要結(jié)束查詢(延遲加載),可以使用 ToCursor()
函數(shù)結(jié)束,程序會(huì)立即開始查詢并將數(shù)據(jù)返回內(nèi)存。
轉(zhuǎn)換查詢
使用 ToEnumerable()
可以使用 Linq 來(lái)查詢文檔。
var list = collection1.Find(new BsonDocument()).ToCursor().ToEnumerable();
過(guò)濾器
前面我們查詢的時(shí)候都使用 .Find(new BsonDocument())
,BsonDocument
是過(guò)濾器對(duì)象,里面存儲(chǔ)了過(guò)濾的規(guī)則,但是我們不能直接設(shè)置 new BsonDocument()
中的屬性,而是使用構(gòu)建器FilterDefinitionBuilder
對(duì)象,而此對(duì)象可以通過(guò) MongoDB.Driver.Builders<TDocument>.Filter
創(chuàng)建 。
假設(shè)有以下數(shù)據(jù)集(文檔):
5f8bdf88e63d14cb5f01dd85 小明 19 5f8bdf88e63d14cb5f01dd86 小紅 20 5f8bdf88e63d14cb5f01dd87 小張 16 5f8bdf88e63d14cb5f01dd88 小小 17 # -----插入數(shù)據(jù)的代碼----- public class Test { public ObjectId _id { get; set; } public string Name { get; set; } public int Age { get; set; } } var datas = new Test[] { new Test{ Name="小明",Age=19}, new Test{ Name="小紅",Age=20}, new Test{ Name="小張",Age=16}, new Test{ Name="小小",Age=17} }; collection.InsertMany(datas);
使用構(gòu)建器:
FilterDefinition<Test> filter = Builders<Test>.Filter
查詢 Age 大于 18 的文檔:
FilterDefinition<Test> filter = filterBuilder.Where(item => item.Age >= 18);
獲取結(jié)果:
Test[] documents = collection.Find(filter).ToEnumerable<Test>().ToArray();
過(guò)濾器還有 Gt()
、In()
、Lte()
等非 Linq 的函數(shù),需要查看文檔學(xué)習(xí)。
Builders<TDocument>
Builders<TDocument>
除了能夠生成過(guò)濾構(gòu)建器,還有其它幾種構(gòu)建器:
// 條件過(guò)濾 public static FilterDefinitionBuilder<TDocument> Filter { get; } // 索引過(guò)濾 public static IndexKeysDefinitionBuilder<TDocument> IndexKeys { get; } // 映射器,相當(dāng)于使用 Linq 的 .Select() 查詢自己只需要的字段 public static ProjectionDefinitionBuilder<TDocument> Projection { get; } // 排序,創(chuàng)建排序規(guī)則,如工具年齡排序 public static SortDefinitionBuilder<TDocument> Sort { get; } // 更新,更新某些字段的值等 public static UpdateDefinitionBuilder<TDocument> Update { get; }
詳細(xì)請(qǐng)參考 https://mongodb.github.io/mongo-csharp-driver/2.10/reference/driver/definitions/#projections
名稱映射
由于 MongoDB 區(qū)分字段的大小寫,文檔的字段一般使用駝峰命名法,首字母小寫,而 C# 字段屬性首字母是 大小開頭的,因此需要不同名稱對(duì)應(yīng)起來(lái)。
可以使用 BsonElement
特性來(lái)設(shè)置映射的名稱。
class Person { [BsonElement("fn")] public string FirstName { get; set; } [BsonElement("ln")] public string LastName { get; set; } }
以上就是 MongoDB 的初入門知識(shí),但是使用了 MongoDB 有什么好處?可以參考這篇文章:http://chabaoo.cn/article/238542.htm
整理場(chǎng)景如下:
存儲(chǔ)應(yīng)用程序日志。日志結(jié)構(gòu)化,查找方便,可以導(dǎo)出其它格式和二次利用。
增加字段不需要改動(dòng)表結(jié)構(gòu),靈活變更。
支持 json 格式導(dǎo)入;類似 json 的數(shù)據(jù)結(jié)構(gòu);能夠很容易還原對(duì)象的屬性,一次性存儲(chǔ)數(shù)據(jù);如果使用傳統(tǒng)數(shù)據(jù)庫(kù),則需要建立多個(gè)表并設(shè)置主鍵外界關(guān)系。
集群。分布式集群海量數(shù)據(jù),容易拓展;故障轉(zhuǎn)移保證服務(wù)可用;
解決分布式文件存儲(chǔ)需求。
索引方式靈活。
到此這篇關(guān)于MongoDB數(shù)據(jù)庫(kù)介紹并用.NET Core對(duì)其進(jìn)行編碼的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
在ASP.NET 2.0中操作數(shù)據(jù)之四十一:DataList和Repeater數(shù)據(jù)分頁(yè)
DataList 和Repeater 都沒(méi)有提供內(nèi)置的分頁(yè)和排序功能,本文主要介紹利用PagedDataSource實(shí)現(xiàn)DataList和Repeater數(shù)據(jù)分頁(yè)。2016-05-05NopCommerce架構(gòu)分析之(八)多語(yǔ)言支持
NopCommerce支持多國(guó)語(yǔ)言,很好的做到了國(guó)際化,我們可以很輕松的下載中文或任意國(guó)家的語(yǔ)言包,上傳進(jìn)行切換,下面就讓我們看看NopCommerce是如何實(shí)現(xiàn)對(duì)多語(yǔ)言的支持的吧。2016-04-04在ASP.NET 2.0中操作數(shù)據(jù)之二:創(chuàng)建一個(gè)業(yè)務(wù)邏輯層
本文主要介紹 ASP.NET 2.0 如何創(chuàng)建業(yè)務(wù)邏輯層,業(yè)務(wù)邏輯層主要定義一些業(yè)務(wù)規(guī)則,調(diào)用已經(jīng)定義好的數(shù)據(jù)庫(kù)訪問(wèn)層代碼,將讀取、插入、修改以及刪除等方法應(yīng)用到合適的業(yè)務(wù)規(guī)則中。2016-04-04在ASP.NET 2.0中操作數(shù)據(jù)之十二:在GridView控件中使用TemplateField
本文主要講解在GridView控件中如何使用TemplateField,從而更加高級(jí)的自定義GridView,實(shí)現(xiàn)自定義列表的功能。2016-05-05在ASP.NET 2.0中操作數(shù)據(jù)之三十:格式化DataList和Repeater的數(shù)據(jù)
本文主要介紹ASP.NET 2.0使用DataList和Repeater如何呈現(xiàn)數(shù)據(jù),一種是在控件的ItemDataBound事件中處理,一種則是在綁定數(shù)據(jù)時(shí)調(diào)用后臺(tái)定義的方法來(lái)實(shí)現(xiàn)。2016-05-05在ASP.NET 2.0中操作數(shù)據(jù)之二十八:GridView里的Button
本文主要介紹ASP.NET 2.0在GridView,DetailsView,FormView都可以包含Buttons,LinkButtons,或ImageButtons.這些button被點(diǎn)擊時(shí),并激發(fā)FormView和DetailsView的ItemCommand事件,GridView的RowCommand事件,根據(jù)CommandName的值來(lái)判斷哪個(gè)button被點(diǎn)擊了,執(zhí)行相應(yīng)的代碼。2016-05-05.NET多種數(shù)據(jù)庫(kù)大數(shù)據(jù)批量插入、更新(支持SqlServer、MySql、PgSql和Oracle)
這篇文章介紹了.NET多種數(shù)據(jù)庫(kù)大數(shù)據(jù)批量插入、更新。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-11-11ASP.NET MVC4入門教程(九):查詢?cè)敿?xì)信息和刪除記錄
本文主要是MVC實(shí)戰(zhàn),介紹如何查詢和刪除信息,進(jìn)行到這一步,您已經(jīng)有一個(gè)完整的MVC案例了,創(chuàng)建、 讀取、 更新、 刪除和搜索等功能也都做了演示。2016-04-04在ASP.NET 2.0中操作數(shù)據(jù)之三十一:使用DataList來(lái)一行顯示多條記錄
ASP.NET 2.0中DataList默認(rèn)情況使用單列多行的table來(lái)顯示項(xiàng),本文介紹通過(guò)設(shè)置RepeatColumns屬性為每行的列數(shù)就可以達(dá)到顯示多條記錄這個(gè)目的。2016-05-05在ASP.NET 2.0中操作數(shù)據(jù)之四十六:使用SqlDataSource控件檢索數(shù)據(jù)
在前面的教程里,我們用ObjectDataSource控件充分的將表現(xiàn)層和數(shù)據(jù)訪問(wèn)層(DAL)分開來(lái)。在這篇教程里我們看看怎樣在一個(gè)表現(xiàn)層和數(shù)據(jù)訪問(wèn)層區(qū)分的不是很嚴(yán)格的簡(jiǎn)單程序中使用SqlDataSource控件。2016-05-05