前言:學習札記!git
以前寫過一篇MongoDB的快速上手文章,裏邊詳細的講了如何安裝、啓動MongoDB,這裏就再也不累述安裝過程,簡單介紹一下Mongodb的基本操做。正則表達式
打開命令行窗口,輸入「mongo」命令,默認會鏈接到test數據庫。sql
l Insertmongodb
db.person.insert({"name":"Olive","age":18})數據庫
db.person.insert({"name":"Momo","age":17})編程
l find數組
db.person.find()//查找全部的person數據安全
{ "_id" :ObjectId("58a03991d57e6773c574e485"), "name" :"Olive", "age" : 18 }服務器
{ "_id" :ObjectId("58a039a8d57e6773c574e486"), "name" :"Momo", "age" : 17 }架構
db.person.find({"name":"Olive"})//查找名爲Olive的person數據
{ "_id" :ObjectId("58a03991d57e6773c574e485"), "name" :"Olive", "age" : 18 }
u "$gt","$gte", "$lt", "$lte", "$ne", "沒有特殊關鍵字"(對應的爲>,>=,<,<=,!=)
db.user.find({"age":{$gt:22}})//年齡大於22
{ "_id" : ObjectId("58a03dc7d57e6773c574e488"),"name" : "joe", "password" : "123456","age" : 25, "address" : { "province" :"henan", "city" : "zhengzhou" },"favourite" : [ "money", "girl" ] }
db.user.find({"age":{$lt:22}})//年齡小於22
{ "_id" :ObjectId("58a03cc0d57e6773c574e487"), "name" :"jack", "password" : "123456", "age" :20, "address" : { "province" : "beijing","city" : "chaoyang" }, "favourite" : ["apple", "banana" ] }
db.user.find({"age":{$ne:25}})//年齡不等於25
{ "_id" :ObjectId("58a03cc0d57e6773c574e487"), "name" :"jack", "password" : "123456", "age" :20, "address" : { "province" : "beijing","city" : "chaoyang" }, "favourite" : ["apple", "banana" ] }
u "無關鍵字「, "$or", "$in","$nin"
db.user.find({$or:[{"name":"jack"},{"age":25}]})//名字爲jack或age爲25的user
{ "_id" :ObjectId("58a03cc0d57e6773c574e487"), "name" :"jack", "password" : "123456", "age" :20, "address" : { "province" : "beijing","city" : "chaoyang" }, "favourite" : ["apple", "banana" ] }
{ "_id" :ObjectId("58a03dc7d57e6773c574e488"), "name" :"joe", "password" : "123456", "age" :25, "address" : { "province" : "henan","city" : "zhengzhou" }, "favourite" : ["money", "girl" ] }
db.user.find({"address.city":{$in:["chaoyang","zhengzhou"]}})//城市爲chaoyang或zhengzhou的user
{ "_id" :ObjectId("58a03cc0d57e6773c574e487"), "name" :"jack", "password" : "123456", "age" :20, "address" : { "province" : "beijing","city" : "chaoyang" }, "favourite" : ["apple", "banana" ] }
{ "_id" :ObjectId("58a03dc7d57e6773c574e488"), "name" :"joe", "password" : "123456", "age" :25, "address" : { "province" : "henan","city" : "zhengzhou" }, "favourite" : ["money", "girl" ] }
db.user.find({"address.city":{$nin:["chaoyang1","zhengzhou"]}})//查找城市不是chaoyang1或不是zhengzhou的user
{ "_id" :ObjectId("58a03cc0d57e6773c574e487"), "name" :"jack", "password" : "123456", "age" :20, "address" : { "province" : "beijing","city" : "chaoyang" }, "favourite" : ["apple", "banana" ] }
u 正則表達式匹配
db.user.find({$or:[{"name":/^j/},{"name":/e$/}]})//匹配名字以j開頭或者名字以e結尾的user
{ "_id" :ObjectId("58a03cc0d57e6773c574e487"), "name" :"jack", "password" : "123456", "age" :20, "address" : { "province" : "beijing","city" : "chaoyang" }, "favourite" : ["apple", "banana" ] }
{ "_id" :ObjectId("58a03dc7d57e6773c574e488"), "name" :"joe", "password" : "123456", "age" :25, "address" : { "province" : "henan","city" : "zhengzhou" }, "favourite" : ["money", "girl" ] }
u $where
db.user.find({$where:function(){return this.name=="joe"}})//用$where的方式查詢名爲joe的user
{ "_id" :ObjectId("58a03dc7d57e6773c574e488"), "name" :"joe", "password" : "123456", "age" :25, "address" : { "province" : "henan","city" : "zhengzhou" }, "favourite" : ["money", "girl" ] }
l Update
db.person.update({"name":"Olive"},{"name":"Olive116","age":19})//更新名爲Olive的person信息
u $inc 修改器(自增$inc指定的值,若是「文檔」中沒有此key,則會建立key,局部修改)
db.user.update({"name":"jack"},{$inc:{"age":10}})
u $set修改器(局部修改age值)
db.user.update({"name":"jack"},{$set:{"age":10}})
u upsert操做(若是沒有查到,就在數據庫裏面新增一條)
db.user.update({"name":"jackson"},{$inc:{"age":1}},true)//更新名爲jackson的age值,若是該user不存在,則新增一條user信息
u 批量更新
db.user.update({「name」:「hxf」},{$inc:{「age」:10}},true)//批量更新名爲hxf的user
l remove
db.person.remove({"name":"Momo"})//移除名爲Momo的person信息
db.user.count({"age":25})//統計age爲25的user個數
db.user.distinct("age")
db.user.group({"key":{"age":true},"initial":{"person":[]},"$reduce":function(cur,prev){prev.person.push(cur.name);}})
key: 這個就是分組的key,咱們這裏是對年齡分組。
initial: 每組都分享一個」初始化函數「,特別注意:是每一組,好比這個的age=20的value的list分享一個initial函數,age=22一樣也分享一個initial函數。
$reduce: 這個函數的第一個參數是當前的文檔對象,第二個參數是上一次function操做的累計對象,第一次爲initial中的{」perosn「:[]}。有多少個文檔, $reduce就會調用多少次。
結果:
[
{
"age" : 10,
"person" : [
"jack"
]
},
{
"age" : 25,
"person" : [
"joe"
]
},
{
"age" : 1,
"person" : [
"jackson"
]
}
]
db.user.group({"key":{"age":true},"initial":{"person":[]},"reduce":function(doc,out){out.person.push(doc.name);},"finallize":function(out){out.count=out.person.length;},"condition":{"age":{$lt:25}}})
user數組裏面的人員太多,想加上一個count屬性標明一下。
針對上面的需求,在group裏面仍是很好辦到的,由於group有這麼兩個可選參數: condition 和 finalize。
condition: 這個就是過濾條件。
finalize:這是個函數,每一組文檔執行完後,多會觸發此方法
結果:
[
{
"age" : 10,
"person" : [
"jack"
]
},
{
"age" : 1,
"person" : [
"jackson"
]
}
]
mapReduce實際上是一種編程模型,用在分佈式計算中,其中有一個「map」函數,一個」reduce「函數。
l map:
這個稱爲映射函數,裏面會調用emit(key,value),集合會按照你指定的key進行映射分組。
l reduce:
這個稱爲簡化函數,會對map分組後的數據進行分組簡化,注意:在reduce(key,value)中的key就是
emit中的key,vlaue爲emit分組後的emit(value)的集合,這裏也就是不少{"count":1}的數組。
l mapReduce:
這個就是最後執行的函數,參數爲map,reduce和一些可選參數
mapfunction(){ emit(this.name,{count:1});
reducefunction(key,value){ var result={count:0}; for(var i=0;i<value.length;i++){result.count+=value[i].count;}return result;}
db.user.mapReduce(map,reduce,{「output」:「collection」});
Mongodb裏的遊標是申明一個查詢結構,並無出具體的數據,只有在遍歷時才加載過來,經過遊標讀取,枚舉完成以後銷燬遊標。
Varlist=db.user.find()
list.Foreach(function(item){print(item.name);});
同時在構造查詢時,還能夠根據須要進行復雜的查詢構造,例如:分頁、排序等
Varlist=db.user.find().sort({「name」,1}).skip(3).limit(3);
在數據庫中插入10萬條數據,以下:
for(vari=0;i<1000000;i++) {
...var rand=parseInt(i*Math.random());
...db.user.insert({"name":"HXF"+i,"age":i})
... }
查找一條數據,並利用「explain」分析函數,進行查詢分析。
db.user.find({"name":"HXF9999"}).explain()
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" :"test.user",
"indexFilterSet" :false,
"parsedQuery" : {
"name" : {
"$eq": "HXF9999"
}
},
"winningPlan" : {
"stage" :"COLLSCAN",
"filter" : {
"name" : {
"$eq" : "HXF9999"
}
},
"direction" :"forward"
},
"rejectedPlans" : [ ]
},
"serverInfo" : {
"host" :"WIN-GJ07N56QAK7",
"port" : 27017,
"version" :"3.0.6",
"gitVersion" :"1ef45a23a4c5e3480ac919b28afcba3c615488f2"
},
"ok" : 1
}
db.user.ensureIndex({「name」:1});
利用ensureIndex方法爲name字段添加索引,「1」表示照name升序,「-1」表示照name降序。
db.user.find({name:「墨遙」}).explain();
db.user.ensureIndex({"name":1},{"unique":true})
建立惟一索引,重複的鍵就不能再插入。
多條件查詢時,能夠經過建立組合索引來加速查詢。
db.user.ensureIndex({"name":1,"birthday":1})
建立組合索引,按照name升序,birthday升序。升序和降序的不一樣都會產生不一樣的索引。
咱們能夠經過getindexes來查看user下建立的全部索引。
db.user.getIndexes();
查詢優化器在作查詢時,會使用咱們創建的這些索引來建立查詢方案,若是某一個先執行完則其餘查詢方案被close掉,這種方案會被mongodb保存起來,固然若是非要用本身指定的查詢方案,這也是能夠的,在mongodb中給咱們提供了hint方法讓咱們能夠暴力執行。
db.user.find({name:‘HXF’,age:27}).hint({age:1,name:1});
db.user.dropIndex(「name_1」)
Mongodb主從複製的部署架構能夠實現數據的備份、數據恢復、讀寫分離。
部署實踐:
在一臺服務器上啓動Mongodb並將該數據庫指定爲主數據庫,命令以下:
mongod --dbpath D:\MangoDB\Data –master
在另外一臺服務器上啓動mongodb並將該數據庫指定爲從數據庫,命令以下:
mongod –dbpath E:\MongoDB\Data –-slave –source=主服務器IP:27017
動態的添加從屬服務器:
在新增的mongodb服務器上,使用local數據庫,並在sources中添加一個host
地址,以下:
在新的mongodb服務器上啓動mongodb數據庫,
use local
db.sources.insert({「host」:」主服務器Ip:端口」});//127.0.0.1:27017
l 讀寫分離
在從屬服務器中,執行rs.slaveOk()便可支持從從屬數據庫讀取信息
副本集也是屬於主從集羣,可是跟上邊的集羣有區別的。
l 副本集的集羣沒有特定的主數據庫
l 若是某個主數據庫宕機了,集羣會自動推選一個從屬數據庫做爲主數據庫頂上,具有了自動故障恢復功能。
實踐以下:
建立集羣,啓動D盤的mongodb程序,指定端口2222,,其中集羣的名字爲HXFX,--replSet表示告知服務器HXFX集羣下還有其餘的數據庫(即指定的端口3333的數據庫)
mongod--dbpath D:\MongoDB\Data --port 2222 --replSet HXFX/127.0.0.1:3333
打開端口爲3333的數據庫
mongod--dbpath D:\SubMongoDB\Data --port 3333 --replSet HXFX/127.0.0.1:2222
鏈接到任意一臺服務器,並以admin登陸數據庫,進行副本集的初始化,命令以下:
mongo127.0.0.1:2222/admin
rs.runCommand({"replSetInitiate":{"_id":"HXFX"},"members":[{"_id":1,"host":"127.0.0.1:2222"},{"_id":2,"host":"127.0.0.1:3333"}]}})
新增一臺服務器,做爲仲裁服務器,以下:
mongod--dbpath D:\ThreeMongoDB\Data --port 4444 --replSet HXFX/127.0.0.3:2222
而後咱們在admin集合中使用rs.addArb()追加便可。以下:
rs.addArb("127.0.0.1:4444")
當數據量達到T級別的時候,mongodb採用將集合進行拆分,將拆分的數據分攤到幾個片上。咱們要了解」片鍵「的概念,也就是說拆分集合的依據是,按照鍵值進行拆分集合。這裏須要一個路由服務器(mongos),根據管理員設置的「片鍵」將數據分攤到本身管理的mongod集羣,同時須要一個config服務器,用來保存數據和片的對應關係以及相應的配置信息。同時還須要若干的mongodb服務器。具體實踐以下:
Config服務主要用來存儲數據和片的對應關係,所應該最早開啓。
--開啓Config服務器
mongod --dbpath D:\SubMongoDB\Data --port 2222
Mongos服務器就是一個路由服務器,同時要爲其指定config服務器
--開啓mongos服務器
mongos --port 3333 --configdb 127.0.0.1:2222
--啓動mongod服務器(4444,5555)
mongod --dbpath D:\ThreeMongoDB\Data --port 4444
mongod --dbpath D:\FourMongoDB\Data --port 5555
--鏈接到mongods服務器並將(4444,5555)服務器添加分片
mongo 127.0.0.1:3333/admin
db.runCommand({"addshard":"127.0.0.1:4444",allowLocal:true})
db.runCommand({"addshard":"127.0.0.1:5555",allowLocal:true})
--開啓數據庫的分片功能
mongo 127.0.0.1:3333/admin
db.runCommand({"enablesharding":"test"})—爲test數據開啓分片功能
--指定集合中分片的鍵
db.runCommand({"shardcollection":"test.user","key":{"name":1}})—指定test數據庫中user集合的name爲片鍵
經過mongos向mongodb中插入10w數據,並經過db.printShardingStatus()來查看效果
插入的1萬條數據分佈在4444和5555服務器上。
Mongod –dbpath D:\MongoDB\Data –-logpath D:\MongoDB\Log\log.txt–port 2222 –install
設置MongoDB數據存儲路徑,日誌路徑,同時開啓了安裝服務寄宿。
經過db.serverStatus()來查看服務器的統計信息(全局鎖、索引、用戶操做行爲等)
經過mongostat實時刷新,觀看數據實時變化。
Mongostat –port 3333
Use admin
Db.system.users.remove({「user」:」XXX」})
Mongodump和mongorestore內置工具,保證不關閉服務器仍能copy數據。使用以下:
Mongodump -–port2222 –d test –o D:\MongoDB\Backup
將test數據庫備份到D盤的mongoDB文件夾下的Backup文件夾下
Mongorestore–-port 2222 –d test –-drop D:\MongoDB\Backup\test
將D:\MongoDB\Backup\test還原到test數據庫,並刪除備份文件
經過加鎖和釋放鎖的方式保證數據,可以所有的備份下來
db.runCommand({"fsync":1,"lock":1})
釋放鎖: db.$cmd.unlock.findOne()
官網驅動示例:(從官網下載Mongodb.net 的驅動)
App.config內容:
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
</startup>
<appSettings><!—配置鏈接字符串、數據庫-->
<add key="ConnString" value="mongodb://127.0.0.1:27017"/>
<add key="DataBase" value="HXFDB"/>
</appSettings>
</configuration>
public staticclass MongoDBFactory
{
privatestatic string conn = ConfigurationManager.AppSettings["ConnString"];
privatestatic string database = ConfigurationManager.AppSettings["DataBase"];
private static MongoClient client = new MongoClient(conn);
privatestatic MongoServer server = client.GetServer();
privatestatic MongoDatabase db = server.GetDatabase(database);
//增
public static void Insert(string name)
{
MongoCollection collection = db.GetCollection("User");
User user = new User() { ID = 0, Name = name, Sex = "男", Age = 27, Code = "MY001" , _id=newBson.ObjectId()};
collection.Insert<User>(user);
QueryDocument query = new QueryDocument { { "Name", name } };
var list = collection.FindAs<User>(query);
foreach (var u in list)
{
Console.WriteLine("Name: {0}, Sex: {1}, Age: {2}, Code: {3}", u.Name,u.Sex, u.Age, u.Code);
}
}
//改
publicstatic void Update1(string name)
{
MongoCollection collection = db.GetCollection("User");
QueryDocument query = new QueryDocument { {"Name",name}};
IMongoUpdate update = Update.Set("Code", "Olive001");
collection.Update(query,update);
var list = collection.FindAllAs<User>();
foreach (var u in list)
{
Console.WriteLine("Name: {0}, Sex: {1}, Age: {2}, Code: {3}", u.Name,u.Sex, u.Age, u.Code);
}
}
//刪
publicstatic void Remove(string name)
{
MongoCollection collection = db.GetCollection("User");
QueryDocument query = new QueryDocument { { "Name", name } };
collection.Remove(query);
var list = collection.FindAllAs<User>();
foreach (var u in list)
{
Console.WriteLine("Name: {0}, Sex: {1}, Age: {2}, Code: {3}", u.Name,u.Sex, u.Age, u.Code);
}
}
//查
publicstatic void Query()
{
MongoCollection collection = db.GetCollection("User");
Console.WriteLine("SELECT * FROM table ");
//SELECT * FROM table
var list = collection.FindAllAs<User>();
foreach (var u in list)
{
Console.WriteLine("Name: {0}, Sex: {1}, Age: {2}, Code: {3}", u.Name,u.Sex, u.Age, u.Code);
}
Console.WriteLine("SELECT * FROM table WHERE Uid > 10 AND Uid< 20");
// sql : SELECT * FROM table WHERE Uid > 10 AND Uid < 20
QueryDocument query = new QueryDocument { };
BsonDocument bd=new BsonDocument ();
bd.Add("$gte",0);
bd.Add("$lt",5);
query.Add("ID", bd);
list = collection.FindAs<User>(query);
foreach (var u in list)
{
Console.WriteLine("Name: {0}, Sex: {1}, Age: {2}, Code: {3}", u.Name,u.Sex, u.Age, u.Code);
}
Console.WriteLine("SELECT Name FROM table WHERE Uid > 10 AND Uid< 20");
// SELECT Name FROM table WHERE Uid > 10 AND Uid < 20
FieldsDocument f = new FieldsDocument();
f.Add("Name", 1);
list = collection.FindAs<User>(query).SetFields(f);
foreach (var u in list)
{
Console.WriteLine("Name: {0}", u.Name);
}
Console.WriteLine("SELECT * FROM table ORDER BY Uid DESC LIMIT10,10");
//SELECT * FROM table ORDER BY Name DESC LIMIT 10,10
SortByDocument s = new SortByDocument();
s.Add("Name", -1);
list = collection.FindAs<User>(query).SetSortOrder(s).SetSkip(1).SetLimit(10);
foreach (var u in list)
{
Console.WriteLine("Name: {0}, Sex: {1}, Age: {2}, Code: {3}", u.Name,u.Sex, u.Age, u.Code);
}
}
}
}