MongoDB常用指令

MongoDB是一種強大、靈活怀大、可擴展的數(shù)據(jù)存儲形式纱兑。他是面向文檔的數(shù)據(jù)庫,是NoSQL的一種化借。它擴展了關(guān)系型數(shù)據(jù)庫的眾多有用功能潜慎,如輔助索引、范圍查詢蓖康、和排序铐炫。還內(nèi)置了對MapReduce式聚合的支持,以及對地理空間索引的支持蒜焊。由于它放棄了關(guān)系型數(shù)據(jù)庫“行”的概念倒信,獲得了更加方便的擴展性。面向文檔的方式可以將文檔或數(shù)組內(nèi)嵌進來泳梆,所以用一條記錄就可以表示很復雜的層次關(guān)系堤结。

MongoDB沒有模式,文檔的鍵不會事先定義也不會固定不變鸭丛。

MongoDB從設(shè)計之初竞穷,就考慮了擴展的問題。他所采用的面向文檔的數(shù)據(jù)模型使之可以自動在多臺服務(wù)器之間分割數(shù)據(jù)鳞溉。它還可以平衡集群的數(shù)據(jù)和負載瘾带,自動重排文檔。如果需要更大的容量時熟菲,只需要向集群中增加新機器看政,數(shù)據(jù)庫就會自動幫我們處理剩下的事情朴恳。

文檔是MongoDB的核心概念。多個鍵及其相關(guān)聯(lián)的值有序的放在一起就是文檔允蚣。MongoDB不但飯區(qū)分類型于颖,還區(qū)分大小寫。

集合collection就是一組文檔嚷兔。MongoDB中的文檔有點類似關(guān)系型數(shù)據(jù)庫中的行森渐,集合有點類似于關(guān)系型數(shù)據(jù)庫中的表。但是與關(guān)系型數(shù)據(jù)庫不同的是冒晰,MongoDB的集合是沒有模式的同衣。但是在同一個集合中使用多種模式,不管對于開發(fā)者還是管理者壶运,都是一個噩夢耐齐。所以我們會使用多個集合。將同種類型的文檔放在同一個集合蒋情,數(shù)據(jù)會更加集中埠况,可以節(jié)省查詢時間,創(chuàng)建索引時也可以變得十分高效棵癣。多個集合可以使我們的查詢更加便捷辕翰,我們不需要從所有的數(shù)據(jù)中找我們需要的,只需要去相應(yīng)的集合中查詢就可以了浙巫。

常用指令

1.創(chuàng)建數(shù)據(jù)庫

MongoDB不需要專門的創(chuàng)建數(shù)據(jù)庫語句金蜀,直接使用use DataBaseName命令,如果數(shù)據(jù)庫存在的畴,則使用該數(shù)據(jù)庫渊抄。如果該數(shù)據(jù)庫不存在,則新建該數(shù)據(jù)庫丧裁。

> use newdb
switched to db newdb

在 MongoDB 中默認數(shù)據(jù)庫是:test

2.刪除數(shù)據(jù)庫

使用db.dropDatabase()命令可以刪除數(shù)據(jù)庫护桦。如果沒有選擇任何數(shù)據(jù)庫,那么它將刪除默認的’test‘數(shù)據(jù)庫

3.查詢數(shù)據(jù)庫列表

>show dbs
local     0.000025GB
test      0.00002GB

4.創(chuàng)建Collection

先通過use DataBaseName命令選中想要創(chuàng)建集合的數(shù)據(jù)庫煎娇,使用命令db.createCollection("collectionName")創(chuàng)建collection

>use newdb
switched to db newdb
>db.createCollection("mycollection")
{ "ok" : 1 }
>

4.刪除集合

MongoDB 的 db.collection.drop() 用于從數(shù)據(jù)庫中刪除集合

5.插入文檔

使用insert()命令插入到MongoDB集合中二庵。

db.CollectionName.insert(
{
    "_id":"100",
    "title":"MongoDB",
    "description":"Description of MongoDB",
    "url":"http://www.baidu.com"
}
)

如果不在文檔中指定_id,insert方法會自動為文檔分配id.
一次插入多個文檔,可以在insert()語句中插入多個文檔缓呛。文檔用逗號隔開催享,再使用中括號把所有文檔括起來。

db.CollectionName.insert([
   {
      _id: 101,
       title: 'MongoDB Guide', 
      description: 'MongoDB is no sql database',
      by: 'yiibai tutorials',
      url: 'http://www.yiibai.com',
      tags: ['mongodb', 'database', 'NoSQL'],
      likes: 100
   },

   {
      _id: 102,
      title: 'NoSQL Database', 
      description: "NoSQL database doesn't have tables",
      by: 'yiibai tutorials',
      url: 'http://www.yiibai.com',
      tags: ['mongodb', 'database', 'NoSQL'],
      likes: 210, 
      comments: [
         {
            user:'user1',
            message: 'My first comment',
            dateCreated: new Date(2017,11,10,2,35),
            like: 0 
         }
      ]
   },
   {
      _id: 104,
      title: 'Python Quick Guide', 
      description: "Python Quick start ",
      by: 'yiibai tutorials',
      url: 'http://www.yiibai.com',
      tags: ['Python', 'database', 'NoSQL'],
      likes: 30, 
      comments: [
         {
            user:'user1',
            message: 'My first comment',
            dateCreated: new Date(2018,11,10,2,35),
            like: 590 
         }
      ]
   }
])

6.查詢文檔

使用db.COLLECTION_NAME.find(document)
查詢文檔哟绊。find()方法會找出collection中的所有文檔因妙。
帶參find()方法,第一個參數(shù)用來指定查詢條件,第二個參數(shù)用來表示要檢索的字段列表攀涵。字段列表對應(yīng)值設(shè)置為1即為顯示铣耘,設(shè)置為0即為隱藏字段。

> db.mycol.find({}, {'_id':1, 'title':1})
{ "_id" : 101, "title" : "MongoDB Guide" }
{ "_id" : 102, "title" : "NoSQL Database" }
{ "_id" : 104, "title" : "Python Quick Guide" }
{ "_id" : 100, "title" : "MongoDB Overview" }
>

第一個參數(shù)可以指定查詢過濾器以故,或類似關(guān)系型數(shù)據(jù)庫指定一些操作符或查詢運算符

>db.mycol.find({"likes": {$gt:10}, $or: [{"by": "yiibai tutorials"},
   {"title": "MongoDB Overview"}]}).pretty()  #and 和 or一起使用
   
{
   "_id": 100,
   "title": "MongoDB Overview", 
   "description": "MongoDB is no sql database",
   "by": "yiibai tutorials",
   "url": "http://www.yiibai.com",
   "tags": ["mongodb", "database", "NoSQL"],
   "likes": "100"
}
>

查詢限制數(shù)量
使用db.COLLECTION_NAME.find().limit(NUMBER)指令可以限制查詢NUMBER條
查詢跳過條目
使用skip()函數(shù)跳過一定量的些條目db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)

7.更新文檔

update方法更新現(xiàn)有文檔中的值db.COLLECTION_NAME.update(SELECTION_CRITERIA, UPDATED_DATA)

>db.mycol.update({'title':'MongoDB Overview'},
   {$set:{'title':'New Update MongoDB Overview'}},{multi:true})

save()方法傳遞新的文檔數(shù)據(jù)替換現(xiàn)有文檔

8.聚合

在關(guān)系型數(shù)據(jù)庫中使用count(*)和group by組合產(chǎn)生聚合功能蜗细,而在MongoDB中應(yīng)該使用aggregate()函數(shù)
假設(shè)我們的集合中有以下數(shù)據(jù)

db.article.insert([
{
   _id: 100,
   title: 'MongoDB Overview',
   description: 'MongoDB is no sql database',
   by_user: 'Maxsu',
   url: 'http://www.yiibai.com',
   tags: ['mongodb', 'database', 'NoSQL'],
   likes: 100
},
{
   _id: 101,
   title: 'NoSQL Overview', 
   description: 'No sql database is very fast',
   by_user: 'Maxsu',
   url: 'http://www.yiibai.com',
   tags: ['mongodb', 'database', 'NoSQL'],
   likes: 10
},
{
   _id: 102,
   title: 'Neo4j Overview', 
   description: 'Neo4j is no sql database',
   by_user: 'Kuber',
   url: 'http://www.neo4j.com',
   tags: ['neo4j', 'database', 'NoSQL'],
   likes: 750
},
{
   _id: 103,
   title: 'MySQL Overview', 
   description: 'MySQL is sql database',
   by_user: 'Curry',
   url: 'http://www.yiibai.com/mysql/',
   tags: ['MySQL', 'database', 'SQL'],
   likes: 350
}])

現(xiàn)在從上面的集合中,如果要顯示一個列表怒详,說明每個用戶寫入了多少個教程炉媒,那么可使用以下aggregate函數(shù)

> db.article.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])
{ "_id" : "Curry", "num_tutorial" : 1 }
{ "_id" : "Kuber", "num_tutorial" : 1 }
{ "_id" : "Maxsu", "num_tutorial" : 2 }
>

9.主從復制

主從復制是MongoDB最常用的復制的方式,可用于備份棘利、故障恢復橱野、讀擴展等朽缴。
首先需要建立一個主節(jié)點和一個或多個從節(jié)點善玫,每個從節(jié)點需要知道主節(jié)點的地址。運行mongod -master啟動主節(jié)點密强。運行mongod --slave --source master_address啟動從節(jié)點茅郎。

生產(chǎn)環(huán)境下可能會有多臺服務(wù)器,我們在同一臺服務(wù)器上替代實驗或渤。首先需要給主節(jié)點建立數(shù)據(jù)目錄系冗,并綁定端口號(10000):

$ mkdir -p ~/dbs/master
$ ./mongod --dbpath ~/dbs/master --port 10000 --master

接著設(shè)置從節(jié)點,需要選擇不同的目錄和端口薪鹦,并且使用--source為從節(jié)點指明主節(jié)點的地址:

$ mkdir -p ~/dbs/slave
$ ./mongod --dbpath ~/dbs/slave --port 10001 --slave --source localhost:10000

這種方式只能從節(jié)點從主節(jié)點復制掌敬,還沒有能夠從從節(jié)點復制的機制,因為從節(jié)點不保存自己的oplog池磁。

10.副本集

副本集是具有自動故障恢復的主從集群奔害。主從集群沒有固定的主節(jié)點,整個集群會推舉出一個主節(jié)點地熄,檔主節(jié)點無法工作時华临,變更到其他的節(jié)點。即端考,副本集總會有一個活躍節(jié)點(primary)和一個或多個備份節(jié)點(secondary)雅潭。
現(xiàn)在我們來將獨立的MongoDB實例轉(zhuǎn)換為副本集。
首先我們需要找到機器的主機名

$ cat /etc/hostname
morton

接著我們要關(guān)機現(xiàn)有的MongoDB服務(wù)器却特,啟動新的服務(wù)器

mongod --port 27017 --dbpath "D:\set up\mongodb\data" --replSet rs0

--replSet的作用是讓服務(wù)器知道扶供,這個rs0服務(wù)器還有其他的同伴還未啟動。
以同樣的方式啟動多臺裂明。
然后在shell中椿浓,連接其中一個服務(wù)器(使用morton:10001),初始化副本集:

$ ./mongo morton:10001/admin

11.MongoDB的關(guān)聯(lián)關(guān)系

MongoDB中的關(guān)系指的是各個文檔之間在邏輯上的相互關(guān)聯(lián)。關(guān)系可以使用嵌入式和引用方法兩種方式構(gòu)建轰绵。這種關(guān)系可以是1:1,1:N,N:N粉寞。
假設(shè)我們需要存儲用戶和用戶的地址。而一個用戶可以有多個地址左腔,這就是一個1:N的關(guān)系唧垦。
以下是用戶文檔結(jié)構(gòu):

{
   "_id":10999110,
   "name": "Maxsu",
   "contact": "13888990021",
   "dob": "1992-10-11"
}

以下是地址(address)文檔的結(jié)構(gòu):

{
   "_id":12200,
   "building": "Hainan Building NO.2100",
   "pincode": 571100,
   "city": "Haikou",
   "province": "Hainan"
}

下面分別通過嵌入式和引用式兩種方式來構(gòu)建關(guān)系:

嵌入式

在嵌入式方法中,我們直接將地址文檔(address)嵌入到用戶(user)文檔中去液样。

{
   "_id": 21000100,
   "contact": "13800138000",
   "dob": "1991-11-11",
   "name": "Maxsu",
   "address": [
      {
         "building": "Hainan Building NO.2100",
         "pincode": 571100,
         "city": "Haikou",
         "province": "Hainan"
      },
      {
         "building": "Sanya Building NO.2100",
         "pincode": 572200,
         "city": "Sanya",
         "province": "Hainan"
      },
   ]
}

這種方式將數(shù)據(jù)保存在同一個文檔中振亮,數(shù)據(jù)的檢索和維護比較容易。

> db.users.findOne({"name":"Maxsu"},{"address":1, "name":1})

但是如果嵌入式文檔不斷增大鞭莽,就會影響到讀寫的性能坊秸。

引用

這是設(shè)計規(guī)范化關(guān)系的方法。 在這種方法中澎怒,用戶和地址文件將分別維護褒搔,但用戶文檔將包含一個將引用地址文檔的id字段的字段。
我們可以將addresswen文檔存在其它的集合中喷面,將其引用添加到用戶文檔即可星瘾。我們使用使用DBRefs來引用文檔。它適用于文檔引用多個集合中的文檔的情況惧辈。

{
   "_id": 21000100,
   "contact": "13800138000",
   "dob": "1991-11-11",
   "name": "Maxsu",
   "address": [
      {
        "$ref":"address_home",
        "$id":ObjectId("12200"),
        "$db":"myDB"   
      },
      {
         "$ref":"address_home",
        "$id":ObjectId("12201"),
        "$db":"myDB"   
      },
   ]
}

DBRefs中有三個字段 -

  • $ref - 此字段指定引用文檔的集合
  • $id - 此字段指定引用文檔的_id字段
  • $db - 這是一個可選字段琳状,并包含引用文檔所在的數(shù)據(jù)庫的名稱
    接下來我們就可以通過引用查到用戶的地址。
>var user = db.users.findOne({"name":"Maxsu"})
>var dbRef = user.address
>db[dbRef.$ref].findOne({"_id":(dbRef.$id)})

12.Map Reduce

Map-reduce是將大量數(shù)據(jù)合并為有用的聚合結(jié)果的數(shù)據(jù)處理范例盒齿。MapReduce通常用于處理大型數(shù)據(jù)集念逞。MongoDB使用MapReduce可以構(gòu)建出大型復雜聚合查詢。
以下是基本 mapReduce 命令的語法 -

>db.collection.mapReduce(
   function() {emit(key,value);},  //map function
   function(key,values) {return reduceFunction}, {   //reduce function
      out: collection,
      query: document,
      sort: document,
      limit: number
   }
)

map-reduce函數(shù)首先查詢集合边翁,然后將結(jié)果文檔映射到發(fā)出的鍵值對翎承,然后根據(jù)具有多個值的鍵進行減少。

在上面的語法 -

map是一個JavaScript函數(shù)倒彰,它將一個值與一個鍵映射并發(fā)出一個鍵值對审洞;
reduce是一個javascript功能,可以減少或分組具有相同鍵的所有文檔待讳;
out指定map-reduce查詢結(jié)果的位置芒澜;
query指定選擇文檔的可選選擇條件;
sort指定可選的排序條件创淡;
limit指定可選的最大文檔數(shù)痴晦;
接下來我們來使用MapReduce
考慮存儲用戶帖子的以下文檔結(jié)構(gòu)。 該文檔存儲用戶的user_name和帖子的狀態(tài)(status)琳彩。

{
   "post_text": "abcd",
   "user_name": "maxsu",
   "status":"active"
}

現(xiàn)在我們需要選出所有status為active的帖子誊酌,并根據(jù)user_name進行分組

>db.posts.mapReduce( 
   function() { emit(this.user_id,1); }, 
   function(key, values) {return Array.sum(values)}, {  
      query:{status:"active"},  
      out:"post_total" 
   }
)

返回結(jié)果

{
   "result" : "post_total",
   "timeMillis" : 9,
   "counts" : {
      "input" : 4,
      "emit" : 4,
      "reduce" : 2,
      "output" : 2
   },
   "ok" : 1,
}

結(jié)果表明:共有4個文檔與查詢匹配部凑,mapper函數(shù)發(fā)出4哥鍵值對文檔,最終將具有相同鍵的reduce函數(shù)分組的映射文檔分解為2碧浊。在MapReduce函數(shù)后直接加find()函數(shù)就可以將我們想要的條目查詢出來涂邀。查詢結(jié)果如下:

{ "_id" : "tom", "value" : 2 }
{ "_id" : "maxsu", "value" : 2 }

13.文本搜索

從MongoDB 2.4開始,默認文本搜索功能是自動啟用狀態(tài)箱锐。
假設(shè)我們需要查詢一些博客比勉。我們先新建blogs集合。然后在blogs集合中插入一些文檔驹止。

db.blogs.insert({_id:1,title:"search",content:"MongoDB search"})
 
db.blogs.insert({_id:2,title:"Map Reduce",content:"Map-reduce"})
 


只有擁有Text index的collection才可以全文檢索浩聋,因此我們需要構(gòu)建Text index。一個collection只能有一個Text index臊恋,但是一個Text index可以有多個字段衣洁。

db.blogs.ensureIndex({title:"text",content:"text"})

接下來我們就可以通過索引去搜索。

簡單的全文搜索
db.blogs.find({$text:{$search:"MongoDB"}})

返回值

{_id:1,title:"search",content:"MongoDB search"}
查詢包含MongoDB不包含Map的記錄
db.blogs.find({$text:{$search:"MongoDB -Map"}})

返回值

{_id:1,title:"search",content:"MongoDB search"}
查詢含有MongoDB search的條目
db.blogs.find({$text:{$search:"\"MongoDB search\""}})
使用權(quán)重排序搜索結(jié)果

默認情況下抖仅,全文搜索是無順序的坊夫,但是我們可以使用$meta textScore來獲得每個文檔對這個搜索的匹配程度,并使用其進行排序


1
db.blogs.find( {$text:{$search:"MongoDB"}}, {score:{$meta:"textScore"}} ).sort({score:{$meta:"textScore"}})
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末岸售,一起剝皮案震驚了整個濱河市践樱,隨后出現(xiàn)的幾起案子厂画,更是在濱河造成了極大的恐慌凸丸,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件袱院,死亡現(xiàn)場離奇詭異屎慢,居然都是意外死亡,警方通過查閱死者的電腦和手機忽洛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門腻惠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人欲虚,你說我怎么就攤上這事集灌。” “怎么了复哆?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵欣喧,是天一觀的道長。 經(jīng)常有香客問我梯找,道長唆阿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任锈锤,我火速辦了婚禮驯鳖,結(jié)果婚禮上闲询,老公的妹妹穿的比我還像新娘。我一直安慰自己浅辙,他們只是感情好扭弧,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著记舆,像睡著了一般寄狼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上氨淌,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天泊愧,我揣著相機與錄音,去河邊找鬼盛正。 笑死删咱,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的豪筝。 我是一名探鬼主播痰滋,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼续崖!你這毒婦竟也來了敲街?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤严望,失蹤者是張志新(化名)和其女友劉穎多艇,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體像吻,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡峻黍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了拨匆。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片姆涩。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖惭每,靈堂內(nèi)的尸體忽然破棺而出骨饿,到底是詐尸還是另有隱情,我是刑警寧澤台腥,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布宏赘,位于F島的核電站,受9級特大地震影響览爵,放射性物質(zhì)發(fā)生泄漏置鼻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一蜓竹、第九天 我趴在偏房一處隱蔽的房頂上張望箕母。 院中可真熱鬧储藐,春花似錦、人聲如沸嘶是。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽聂喇。三九已至辖源,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間希太,已是汗流浹背克饶。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留誊辉,地道東北人矾湃。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像堕澄,于是被迫代替她去往敵國和親邀跃。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容