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..tgz

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

mv mongodb-linux-x86_64-rhel70-4.2./ /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=
dbpath=/usr/local/mongodb/data/
logpath=/usr/local/mongodb/log/mongodb.log
pidfilepath =/usr/local/mongodb/run/mongodb.pid
logappend=true
fork=true
maxConns=
noauth = true # 配置解釋:
# fork=true 執行在後臺
# logappend=true 如果為 true,當 mongod/mongos 重啟後,將在現有日誌的尾部繼續新增日誌。否則,將會備份當前日誌檔案,然後建立一個新的日誌檔案;預設為 false。
# noauth = true 不需要驗證使用者密碼
# maxConns= 最大同時連線數 預設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:,gender:"男"})

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

查詢資料

db.xyj.find()

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

新增一條指定id的資料

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

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

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

批量新增資料

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

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

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

總結:

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

額外小知識

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

可以知道那條插入失敗

全量修改操作

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

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

區域性修改操作

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

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

批量修改

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

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

欄位增加操作

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

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

刪除檔案

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

刪除檔案欄位

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

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

刪除所有

db.xyj.remove({})  

陣列操作

插入測試資料

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

新增陣列內容($push)

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

刪除元素($pop

刪除最後一個元素

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

刪除第一個元素

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

刪除特定元素($pull

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

新增一條測試資料

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

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

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

陣列查詢:

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

多個元素的查詢

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

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

限制陣列長度查詢

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

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

投影查詢

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

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()}},{age:{$lt:NumberInt()}}]})
//查詢名字裡有”精“的或者年紀大於30的
db.xyj.find({$or:[{age:{$gt:NumberInt()}},{name:/精/}]})

比較查詢:

db.xyj.find({age:{$gt:NumberInt()}})  //查詢年級大於20歲的

$gt--》大於     $lt--》小於   $gte--》大於等於     $lte--》小於等於   $ne---》不等於(不等於不一定要用於數字)

包含查詢:

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

不包含:

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

Like:

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

統計查詢:

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

取模:

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

是否存在($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:,tags:['animal','dog'],type:'dog',money:[{min:},{norm:},{big:}]});

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

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

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

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

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

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

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':}},
{$project:{_id:,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:}}
)