1. 程式人生 > >MongoDB安裝和入門

MongoDB安裝和入門

什麼是MongoDB

MongoDB是一個文件資料庫,提供好的效能,領先的非關係型資料庫。採用BSON儲存文件資料。2007年10月,MongoDB由10gen團隊所發展。2009年2月首度推出。MongoDB用c++編寫的。

優勢:
  • 面向文件的儲存:以 JSON 格式的文件儲存資料。

  • 任何屬性都可以建立索引。

  • 複製以及高可擴充套件性。

  • 自動分片。

  • 豐富的查詢功能。

  • 快速的即時更新。

  • 來自 MongoDB 的專業支援。

mongodb安裝與啟動

mongodb下載網址: https://www.mongodb.com/download-center/community

選擇版本、系統環境、包 。以下將以tgz包 為例

下載完成將得到mongodb-linux-x86_64-rhel70-4.2.8.tgz包,將其上傳到linux(centos7)某個目錄

上傳完成後解壓

tar zxvf mongodb-linux-x86_64-rhel70-4.2.8.tgz

移動到/usr/local/mongodb目錄(非必須)

mv mongodb-linux-x86_64-rhel70-4.2.8/ /usr/local/mongodb

建立專門的負責的使用者並賦予許可權(非必須)

cd /usr/local/mongodb 
groupadd mongodb
useradd -s /sbin/nologin -g mongodb -M mongodb
mkdir data log run
chown -R mongodb:mongodb data log run

在/usr/local/mongodb 裡面建立一個配置檔案 mongodb.conf

vim mongodb.conf 並寫入下面的資訊:

bind_ip=0.0.0.0
port=27017
dbpath=/usr/local/mongodb/data/
logpath=/usr/local/mongodb/log/mongodb.log
pidfilepath =/usr/local/mongodb/run/mongodb.pid
logappend=true
fork=true    
maxConns=500
noauth = true


# 配置解釋:
# fork=true   執行在後臺
# logappend=true  如果為 true,當 mongod/mongos 重啟後,將在現有日誌的尾部繼續新增日誌。否則,將會備份當前日誌檔案,然後建立一個新的日誌檔案;預設為 false。
# noauth = true  不需要驗證使用者密碼
# maxConns=500 最大同時連線數 預設2000

以上是MongoDB的安裝與啟動的準備工作,可直接啟動 啟動命令:

/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/mongodb.conf

配置環境變數

vim /etc/profile 

在/etc/profile檔案末尾新增一行:

export PATH=/usr/local/mongodb/bin:$PATH

讓其生效:

source /etc/profile

檢視當前mongodb的版本:

mongod --version

 

 

 

MongoDB的crud

理解幾個概念

集合:對應mysql的table

文件:對應mysql的一條資料

 

資料庫的操作

連線MongoDB,執行mongo命令

mongo

 

 

 檢視MongoDB自帶的原始資料庫

show dbs

 

 

 

 

 

 

admin:從許可權角度來看,這是“root”資料庫。如果將一個使用者新增到這個資料庫。這個使用者自動繼承所有資料庫的許可權。一些特定的伺服器端命令也只能從這個資料庫執行,比如列出所有的資料庫或者關閉伺服器

local:這個資料永遠不會被複制,可以用來儲存限於本地單臺伺服器的任意集合

config:當mongo用於分片設定時,config資料庫在內部使用。用於儲存分片的相關資訊

 

建立或進入資料庫:use 資料庫名

use test

使用use時,如果資料庫存在則會進入到相應的資料庫,如果不存在則會自動建立  一旦進入資料庫,則可以使用db來引用當前庫 ;

如果是第一次建立,那個這個資料庫只是存在於記憶體當中,直到這個資料庫中建立了集合後才會持久化到磁碟上

 

 

 

刪除資料庫:db.dropDatabase()

db.dropDatabase()

 

 

集合的操作

 用於刪除已經持久化的資料庫,剛建立在記憶體中的資料庫刪除無效

相當於恢復到剛建立test資料庫且並沒有持久化到磁碟的狀態

建立一個集合:db.createCollection("集合名稱")

db.createCollection("西遊記")

 

 

 

檢視所有的集合show tables 或者 show collections

show tables
show collections

 

 

 

刪除集合:db.集合名稱.drop()

db.西遊記.drop()

 

 

 

文件的操作

新增一條資料

db.xyj.insert({name:"豬八戒",age:28,gender:"男"})

這裡會自動建立xyj這個集合

 

查詢資料

db.xyj.find()

 

 

 可以看到,我們沒有指定id,MongoDB自動給我們生成了一條id,我們也可以指定id,如下

 

新增一條指定id的資料

db.xyj.insertOne({_id:"workd",name:"豬八戒",age:28,gender:"男"})

 

 

 當我們向集合中插入文件時,如果沒有給文件指定 _id屬性,則資料庫會自動為文件新增 _id該屬性用來作為文件的唯一標識 _id

我們可以自己指定,如果我們指定了資料庫就不會在添加了,如果自己指定 _id 也必須確保它的唯一性

 

批量新增資料

db.xyj.insert([
...      {name:"沙和尚",age:38,gender:"男"},
...      {name:"白骨精",age:16,gender:"女"},
...      {name:"蜘蛛精",age:14,gender:"女"}
... ])

 

 

 或者以下命令也是一樣的效果

db.xyj.insertMany([
     {name:"沙和尚",age:38,gender:"男"},
     {name:"白骨精",age:16,gender:"女"},
     {name:"蜘蛛精",age:14,gender:"女"}
])

 

 

 總結:

  db.collection.insertOne() 插入一個文件物件
  db.collection.insertMany() 插入多個文件物件

 

額外小知識

try{
    db.xyj.insert([
      {name:"沙和尚",age:38,gender:"男"},
      {name:"白骨精",age:16,gender:"女"},
      {name:"蜘蛛精",age:14,gender:"女"}
    ]);
}catch(e){
    print(e)
}

可以知道那條插入失敗

全量修改操作

db.xyj.update({_id: ObjectId("5f0189a368c6a000f725c87b")},{age:NumberInt(30)})

 

 

 執行效果:這條資料只有age一個欄位了

 

區域性修改操作

db.xyj.update({_id:ObjectId("5f0189a368c6a000f725c87c")},{$set:{age:NumberInt(30)}})

 

 

 執行效果:只會修改這條資料的某個欄位

 

批量修改

db.xyj.update({name:"蜘蛛精"},{$set:{age:NumberInt(100)}},{multi:true})

 

 

 注意:在修改條資料時,必須要加上第三個引數{multi:true},否則只會修改一條資料

 

欄位增加操作

db.xyj.update({_id:"workd"},{$inc:{age:NumberInt(1)}})

 

 

 注意:$inc對應的欄位必須是數字,而且遞增或遞減的值也必須是數字。

 

刪除文件

db.xyj.remove({_id:"workd"})

 

 

 

刪除文件欄位

db.xyj.update({"_id": ObjectId("5f0189a368c6a000f725c87d")}, {"$unset": {"name":1}})

$unset指定欄位的值只需是任意合法值即可

 

 

 

刪除所有

db.xyj.remove({})  

 

 

 

 

 

 

陣列操作

插入測試資料

db.xyj.insertMany([
     {name:"沙和尚",age:38,gender:"男",hobby:["打籃球","吃喝"]},
     {name:"白骨精",age:16,gender:"女",hobby:["吃喝"]},
     {name:"蜘蛛精",age:14,gender:"女",hobby:["跑步","打乒乓球"]},
     {name:"唐生",age:25,gender:"男",hobby:["坐禪","吃喝"]}
]);

 

新增陣列內容($push)

db.xyj.update({"name": "白骨精"}, {"$push": {"hobby": "唸佛"}})

 

 

 刪除元素($pop

刪除最後一個元素

db.xyj.update({"_id": ObjectId("5f019375caf12a975c177d10")}, {"$pop": {"hobby": 1}})

 

 

 

刪除第一個元素

db.xyj.update({"_id": ObjectId("5f019375caf12a975c177d13")}, {"$pop": {"hobby": -1}})

 

 

 

刪除特定元素($pull

db.xyj.update({"_id": ObjectId("5f019375caf12a975c177d11")}, {"$pull": {"hobby": "唸佛" }})

 

 

 

新增一條測試資料

db.xyj.insert({name:"豬八戒",age:28,gender:"男",address: [{place: "nanji", tel: 123}, {place: "dongbei", tel: 321}]});

更新巢狀陣列的值($set)

db.xyj.update({"_id": ObjectId("5f019881caf12a975c177d14")}, {"$set": {"address.0.tel": 213}})

 

 

 陣列查詢:

db.xyj.find({"hobby":"跑步"})

多個元素的查詢

db.xyj.find({"hobby":{"$all": ["跑步", "打乒乓球"]}})

只有hobby陣列同時存在跑步和打乒乓球才會匹配

限制陣列長度查詢

db.xyj.find({"hobby": {"$size": 1}})

只有陣列的長度是1才會匹配

 

 

投影查詢

db.xyj.find({name:"白骨精"},{name:1,_id:0})

1表示顯示 0表示強制隱藏

相當於sql裡面只查某些欄位

按欄位條件查詢

db.xyj.find({name:"白骨精"})

 

 按欄位條件查詢並只返回一條

db.xyj.findOne({gender:"女"})

 

 

其他api就不都演示了

組合查詢:

語法:db.xyj.find($and:[{},{},{}])
//查詢年級大於20小於50的
db.xyj.find({$and:[{age:{$gt:NumberInt(20)}},{age:{$lt:NumberInt(50)}}]})  
//查詢名字裡有”精“的或者年紀大於30的
db.xyj.find({$or:[{age:{$gt:NumberInt(30)}},{name:/精/}]})  

比較查詢:

db.xyj.find({age:{$gt:NumberInt(20)}})  //查詢年級大於20歲的
 
$gt--》大於     $lt--》小於   $gte--》大於等於     $lte--》小於等於   $ne---》不等於(不等於不一定要用於數字)

包含查詢:

 db.xyj.find({age:{$in:[28,38]}})

不包含:

 db.xyj.find({age:{$nin:[28,38]}})

Like:

db.xyj.find({"name": /精/})

統計查詢:

db.xyj.count()或者db.xyj.count({欄位:條件})

取模:

db.xyj.find({"age": {$mod: [5, 1]}})
比如我們要匹配 age % 5 == 1

是否存在($exists)

db.xyj.find({"love": {"$exists": true}})  // 如果存在欄位love,就返回
db.xyj.find({"love": {"$exists": false}}) // 如果不存在欄位love,就返回

 

分頁查詢

limit:顯示幾條記錄

skip:跳過幾條記錄

第一次查詢:db.xyj.find().limit(2)

第一次查詢:db.xyj.find().limit(2).skip(2)

結合排序:db.xyj.find().limit(2).skip(2).sort({age:1}) // 1代表升序,-1代表降序

執行順序: sort > skip > limit

 

聚合管道

較常見的管道操作符以及他們的作用:

操作符描述語法
$project 資料投影,主要用於重新命名,增加,刪除欄位 db.article.aggregate({ $project : {title : 1 ,author : 1 ,}});
$match 過濾,篩選符合條件的文件,作為下一階段輸入 db.articles.aggregate( [{ $match : { score : { $gt : 70, $lte : 90 } } },{ $group: { _id: null, count: { $sum: 1 } } }] );
$limit 限制經過管道的文件數量 db.article.aggregate({ $limit : 5 });
$skip 待操作集合處理前跳過部分文件 db.article.aggregate({ $skip : 5 });
$unwind 將陣列拆分成獨立欄位 db.article.aggregate({$project:{author:1,title:1,tags:1}},{$unwind:"$tags"})
$group 對資料進行分組 db.article.aggregate({ $group : {_id : "$author",docsPerAuthor : { $sum : 1 },viewsPerAuthor : { $sum : "$pageViews" }}});
$sort 對文件按照指定欄位排序 db.users.aggregate( { $sort : { age : -1, posts: 1 } });
$sample 隨機選擇從其輸入指定數量的文件。 { $sample: { size: <positive integer> } }
$out 必須為pipeline最後一個階段管道,因為是將最後計算結果寫入到指定的collection中  
$indexStats 返回資料集合的每個索引的使用情況 { $indexStats: { } }

 

插入測試資料

document1=({name:'dogOne',age:1,tags:['animal','dog'],type:'dog',money:[{min:100},{norm:200},{big:300}]});

document2=({name:'catOne',age:3,tags:['animal','cat'],type:'cat',money:[{min:50},{norm:100},{big:200}]});

document3=({name:'catTwo',age:2,tags:['animal','cat'],type:'cat',money:[{min:20},{norm:50},{big:100}]});

document4=({name:'dogTwo',age:5,tags:['animal','dog'],type:'dog',money:[{min:300},{norm:500},{big:700}]});

document5=({name:'appleOne',age:0,tags:['fruit','apple'],type:'apple',money:[{min:10},{norm:12},{big:13}]});

document6=({name:'appleTwo',age:0,tags:['fruit','apple'],type:'apple',money:[{min:10},{norm:12},{big:13}]});

document7=({name:'pineapple',age:0,tags:['fruit','pineapple'],type:'pineapple',money:[{min:8},{norm:9},{big:10}]});

db.mycol.insert(document1)

db.mycol.insert(document2)

db.mycol.insert(document3)

db.mycol.insert(document4)

db.mycol.insert(document5)

db.mycol.insert(document6)

db.mycol.insert(document7)

 

 假定我們想提取money中min為100的文件,並且只輸出名稱和money陣列中的min那一項

db.mycol.aggregate(
   {$match:{'money.min':100}},
   {$project:{_id:0,name:'$name',minprice:'$money.min'}}
)

假定我們想提取money中min小於100的文件,並且限制3個文件,跳過一個文件再顯示

 

 通過type型別來對資料進行分類,並且同時統計他們的年齡age總和

db.mycol.aggregate(
    {$group:{_id:'$type',sumage:{$sum:'$age'}}}
)

 

 按照年齡對資料進行排序

db.mycol.aggregate(
    {$group:{_id:'$type',sumage:{$sum:'$age'}}},
    {$sort:{sumage:1}}
)

&n