MongoDB 不同的連接方式
首先啟動服務(bin 目錄下執行 mongodb)
使用 MongoDB shell 連接服務器
標准URL連接語法
mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
- mongodb:固定格式,必須指定
- username:password@:可選項,設置后在連接后會嘗試登陸數據庫
- host1:必須置頂至少一個 host ;如果要連接復制集,需要指定多個地址
- portX :可選的指定端口,默認是27017
- /database :如果指定賬號密碼,連接驗證登陸指定數據庫;否則打開 test 數據庫
- ?options :連接選項,所有連接選項都是鍵值對 name=value,鍵值對之間通過“ & ”或 “ ;”隔開
連接選項 options:
選項 | 描述 |
---|---|
replicaSet=name | 驗證replica set的名稱。 Impliesconnect=replicaSet. |
slaveOk=true|false | true:在connect=direct模式下,驅動會連接第一台機器,即使這台服務器不是主。在connect=replicaSet模式下,驅動會發送所有的寫請求到主並且把讀取操作分布在其他從服務器。false: 在 connect=direct模式下,驅動會自動找尋主服務器. 在connect=replicaSet 模式下,驅動僅僅連接主服務器,並且所有的讀寫命令都連接到主服務器。 |
safe=true|false | true: 在執行更新操作之后,驅動都會發送getLastError命令來確保更新成功。(還要參考 wtimeoutMS).false: 在每次更新之后,驅動不會發送getLastError來確保更新成功。 |
w=n | 驅動添加 { w : n } 到getLastError命令. 應用於safe=true。 |
wtimeoutMS=ms | 驅動添加 { wtimeout : ms } 到 getlasterror 命令. 應用於 safe=true. |
fsync=true|false | true: 驅動添加 { fsync : true } 到 getlasterror 命令.應用於 safe=true.false: 驅動不會添加到getLastError命令中。 |
journal=true|false | 如果設置為 true, 同步到 journal (在提交到數據庫前寫入到實體中). 應用於 safe=true |
connectTimeoutMS=ms | 可以打開連接的時間。 |
socketTimeoutMS=ms | 發送和接受sockets的時間。 |
實例
使用默認端口連接服務
mongodb://localhost
通過 shell 連接服務
./mongo
# 使用賬號密碼連接到本地服務
mongodb://admin:123456@localhost/
# 使用賬號密碼連接登陸到指定數據庫
mongodb://admin:123456@localhost/test
其他連接實例
mongodb://localhost
mongodb://fred:foobar@localhost
mongodb://fred:foobar@localhost/baz
# 連接 replica pair 服務器 1 為 example1.com,2 為 example2.com
mongodb://example1.com:27017,example2.com:27017
# 連接 replica set 三台服務器 (端口 27017, 27018, 和27019)
mongodb://localhost,localhost:27018,localhost:27019
# 連接 replica set 三台服務器, 寫入操作應用在主服務器 並且分布查詢到從服務器。
mongodb://host1,host2,host3/?slaveOk=true
# 直接連接第一個服務器,無論是replica set一部分或者主服務器或者從服務器。
mongodb://host1,host2,host3/?connect=direct;slaveOk=true
# 安全模式連接到localhost:
mongodb://localhost/?safe=true
# 以安全模式連接到replica set,並且等待至少兩個復制服務器成功寫入,超時時間設置為2秒。
mongodb://host1,host2,host3/?safe=true;w=2;wtimeoutMS=2000
數據庫操作
創建數據庫
在 MongoDB 中,集合只有在內容插入后才會創建
就是說,創建集合(數據表)后要再插入一個文檔(記錄),集合才會真正創建。
# 如果數據庫不存在則創建,否則切換到這個數據庫
use DATABASE_NAME
use newtest
# 查看當前數據庫,新創建的數據庫未在列表中顯示
show dbs
# 插入數據后再次查詢即可顯示
db.newtest.insert({"name":"測試"})
show dbs
刪除數據庫
# 刪除當前數據庫,默認為 test
db.dropDatabase()
集合操作
創建集合
如果在不存在的集合中直接插入文檔,則集合會自動被創建
# 語法
db.createCollection(name,options)
# 例子
# 指定大小為 6142800 字節,文檔最大數量 10000,建立 _id 索引
db.createCollection("mycol",{capped:true,autoIndexId:true,size:6142800,max:10000})
- name:要創建的集合名稱
- options:可選參數,制定有關內存大小及索引的選項
options 可選項
字段 | 類型 | 描述 |
---|---|---|
capped | 布爾 | (可選)如果為 true,則創建固定集合。固定集合是指有着固定大小的集合,當達到最大值時,它會自動覆蓋最早的文檔。 當該值為 true 時,必須指定 size 參數。 |
autoIndexId | 布爾 | 3.2 之后不再支持該參數。(可選)如為 true,自動在 _id 字段創建索引。默認為 false。 |
size | 數值 | (可選)為固定集合指定一個最大值,即字節數。 如果 capped 為 true,也需要指定該字段。 |
max | 數值 | (可選)指定固定集合中包含文檔的最大數量。 |
刪除集合
# 語法
db.<集合>.drop()
# 查看是否刪除
show collections
文檔操作
插入文檔
語法
使用 insert() 或 save() 方法向集合中插入文檔,語法如下:
# 語法
db.<collection>.insert(<document>)
db.<collection>.save(<document>)
- save():如果 _id 主鍵存在則更新數據,如果不存在就插入數據。該方法新版本中已廢棄,可以使用 db.collection.insertOne() 或 db.collection.replaceOne() 來代替。
- insert(): 若插入的數據主鍵已經存在,則會拋 org.springframework.dao.DuplicateKeyException 異常,提示主鍵重復,不保存當前數據。
# 新版語法
# 單插
db.<collection>.insertOne(
<document>,
{
writeConcern: <document>
}
)
# 多插
db.<collection>.insertMany(
[ <document 1> , <document 2>, ... ],
{
writeConcern: <document>,
ordered: <boolean>
}
)
- document:要寫入的文檔。
- writeConcern:寫入策略,默認為 1,即要求確認寫操作,0 是不要求。
- ordered:指定是否按順序寫入,默認 true,按順序寫入。
實例
# 向 col 集合插入一個文檔
>db.col.insert({title: 'MongoDB 教程',
description: 'MongoDB 是一個 Nosql 數據庫',
by: '菜鳥教程',
url: 'http://www.runoob.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
})
# 查看
> db.col.find()
{ "_id" : ObjectId("56064886ade2f21f36b03134"), "title" : "MongoDB 教程", "description" : "MongoDB 是一個 Nosql 數據庫", "by" : "菜鳥教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }
>
---
# 先定義變量法
> document=({title: 'MongoDB 教程',
description: 'MongoDB 是一個 Nosql 數據庫',
by: '菜鳥教程',
url: 'http://www.runoob.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
});
# 插入變量
> db.col.insert(document)
WriteResult({ "nInserted" : 1 })
更新文檔
語法
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
}
)
- query : update的查詢條件,類似sql update查詢內where后面的。
- update : update的對象和一些更新的操作符(如$,$inc...)等,也可以理解為sql update查詢內set后面的
- upsert : 可選,這個參數的意思是,如果不存在update的記錄,是否插入objNew,true為插入,默認是false,不插入。
- multi : 可選,mongodb 默認是false,只更新找到的第一條記錄,如果這個參數為true,就把按條件查出來多條記錄全部更新。
- writeConcern :可選,拋出異常的級別。
實例
# 插入數據
>db.col.insert({
title: 'MongoDB 教程',
description: 'MongoDB 是一個 Nosql 數據庫',
by: '菜鳥教程',
url: 'http://www.runoob.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
})
# 更新數據,更新標題
>db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) # 輸出信息
# 查看
> db.col.find().pretty()
{
"_id" : ObjectId("56064f89ade2f21f36b03136"),
"title" : "MongoDB",
"description" : "MongoDB 是一個 Nosql 數據庫",
"by" : "菜鳥教程",
"url" : "http://www.runoob.com",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 100
}
>
刪除文檔
語法
db.collection.remove(
<query>,
{
justOne: <boolean>,
writeConcern: <document>
}
)
- query :(可選)刪除的文檔的條件。
- justOne : (可選)如果設為 true 或 1,則只刪除一個文檔,如果不設置該參數,或使用默認值 false,則刪除所有匹配條件的文檔。
- writeConcern :(可選)拋出異常的級別。
實例
# 刪除符合條件的文檔
>db.col.remove({'title':'MongoDB 教程'})
WriteResult({ "nRemoved" : 2 }) # 刪除了兩條數據
# 刪除全部
>db.col.remove({})
查詢文檔
語法
MongoDB 使用 find() 方法以非結構化的方式來顯示文檔
# 查詢
db.collection.find(query, projection)
db.collection.findOne(query, projection)
# 如果你需要以易讀的方式來讀取數據,可以使用 pretty() 方法,語法格式如下:
db.col.find().pretty()
db.col.findOne().pretty()
- query :可選,使用查詢操作符指定查詢條件
- projection :可選,使用投影操作符指定返回的鍵。查詢時返回文檔中所有鍵值, 只需省略該參數即可(默認省略)。
條件語句
操作 | 格式 | 范例 | RDBMS中的類似語句 |
---|---|---|---|
等於 | {<key>:<value> } |
db.col.find({"by":"菜鳥教程"}).pretty() |
where by = '菜鳥教程' |
小於 | {<key>:{$lt:<value>}} |
db.col.find({"likes":{$lt:50}}).pretty() |
where likes < 50 |
小於或等於 | {<key>:{$lte:<value>}} |
db.col.find({"likes":{$lte:50}}).pretty() |
where likes <= 50 |
大於 | {<key>:{$gt:<value>}} |
db.col.find({"likes":{$gt:50}}).pretty() |
where likes > 50 |
大於或等於 | {<key>:{$gte:<value>}} |
db.col.find({"likes":{$gte:50}}).pretty() |
where likes >= 50 |
不等於 | {<key>:{$ne:<value>}} |
db.col.find({"likes":{$ne:50}}).pretty() |
where likes != 50 |
and 條件
# 多個條件以逗號隔開
db.col.find({key1:value1, key2:value2}).pretty()
# 例如
db.col.find({"by":"菜鳥教程", "title":"MongoDB 教程"}).pretty()
or 條件
# 使用 $or 關鍵字
db.col.find({$or: [{key1: value1}, {key2:value2}]}).pretty()
# 例如
db.col.find({$or:[{"by":"菜鳥教程"},{"title": "MongoDB 教程"}]}).pretty()
組合使用實例
db.col.find({"likes": {$gt:50}, $or: [{"by": "菜鳥教程"},{"title": "MongoDB 教程"}]}).pretty()
條件操作符
- (>) 大於 - $gt
- (<) 小於 - $lt
- (>=) 大於等於 - $gte
- (<= ) 小於等於 - $lte
- $type,指定查詢的數據類型
指定數量:Limit() 和 Skip()
# limit 指定讀取的條數
db.COLLECTION_NAME.find().limit(NUMBER)
# skip 跳過指定數量的數據
db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
排序 sort()
# 指定排序的字段, 1 是升序排列,-1 是降序排列
db.COLLECTION_NAME.find().sort({KEY:1})
索引
索引可以極大的提高查詢效率
索引是一種特殊的數據結構,存儲在一個易於遍歷讀取的數據集合中,是對數據庫表中一列或多列的值進行排序的一種結構
createIndex() 方法
# 創建 key 的索引
db.collection.createIndex(key,options)
# 例 1,給 title 字段升序創建索引
db.col.createIndex({"title":1})
# 例 2,按 title 字段升序,description 字段降序,創建索引
db.col.createIndex({"title":1,"description":-1})
# 例 3,使用 background 參數在后台建立索引
db.values.createIndex({open: 1, close: 1}, {background: true})
Parameter | Type | Description |
---|---|---|
background | Boolean | 建索引過程會阻塞其它數據庫操作,background可指定以后台方式創建索引,即增加 "background" 可選參數。 "background" 默認值為false。 |
unique | Boolean | 建立的索引是否唯一。指定為true創建唯一索引。默認值為false. |
name | string | 索引的名稱。如果未指定,MongoDB的通過連接索引的字段名和排序順序生成一個索引名稱。 |
dropDups | Boolean | 3.0+版本已廢棄。在建立唯一索引時是否刪除重復記錄,指定 true 創建唯一索引。默認值為 false. |
sparse | Boolean | 對文檔中不存在的字段數據不啟用索引;這個參數需要特別注意,如果設置為true的話,在索引字段中不會查詢出不包含對應字段的文檔.。默認值為 false. |
expireAfterSeconds | integer | 指定一個以秒為單位的數值,完成 TTL設定,設定集合的生存時間。 |
v | index version | 索引的版本號。默認的索引版本取決於mongod創建索引時運行的版本。 |
weights | document | 索引權重值,數值在 1 到 99,999 之間,表示該索引相對於其他索引字段的得分權重。 |
default_language | string | 對於文本索引,該參數決定了停用詞及詞干和詞器的規則的列表。 默認為英語 |
language_override | string | 對於文本索引,該參數指定了包含在文檔中的字段名,語言覆蓋默認的language,默認值為 language. |
其他索引方法
# 查看集合索引
db.col.getIndexes()
# 查看集合索引大小
db.col.totalIndexSize()
# 刪除集合所有索引
db.col.dropIndexes()
# 刪除集合指定索引
db.col.dropIndex("索引名稱")
聚合方法
用於處理數據,如統計平均值,求和等操作,類似 SQL 語句中的 count(*)
aggregate() 方法
db.col.aggregate(AGGREGATE_OPERATION)
# 其中 AGGREGATE_OPERATION
# 例1 求和
db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])
# 類似於 SQL 的: select by_user, count(*) from mycol group by by_user
# 例1 格式處理后
db.mycol.aggregate(
[
{
$group : {
_id : "$by_user", num_tutorial : {$sum : 1}
}
}
]
)
聚合表達式
表達式 | 描述 | 實例 |
---|---|---|
$sum | 計算總和。 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}]) |
$avg | 計算平均值 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}]) |
$min | 獲取集合中所有文檔對應值得最小值。 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}]) |
$max | 獲取集合中所有文檔對應值得最大值。 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}]) |
$push | 將值加入一個數組中,不會判斷是否有重復的值。 | db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}]) |
$addToSet | 將值加入一個數組中,會判斷是否有重復的值,若相同的值在數組中已經存在了,則不加入。 | db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}]) |
$first | 根據資源文檔的排序獲取第一個文檔數據。 | db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}]) |
$last | 根據資源文檔的排序獲取最后一個文檔數據 | db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}]) |
管道
管道在 Unix 和 Linux 中用於將當前命令的輸出結果作為下一個命令的參數
MongoDB 的聚合管道將文檔在一個管道處理完畢后,將結果傳遞給下一個管道處理,管道操作是可以重復的
表達式:處理輸入文檔並輸出。是無狀態的,只能用於計算按當前聚合管道的文檔,不能處理其他的文檔
聚合框架的常用操作:
- $project:修改輸入文檔的結構。可以用來重命名、增加或刪除域,也可以用於創建計算結果以及嵌套文檔。
- $match:用於過濾數據,只輸出符合條件的文檔。$match使用MongoDB的標准查詢操作。
- $limit:用來限制MongoDB聚合管道返回的文檔數。
- $skip:在聚合管道中跳過指定數量的文檔,並返回余下的文檔。
- $unwind:將文檔中的某一個數組類型字段拆分成多條,每條包含數組中的一個值。
- $group:將集合中的文檔分組,可用於統計結果。
- $sort:將輸入文檔排序后輸出。
- $geoNear:輸出接近某一地理位置的有序文檔。
# 兩個管道的例子
# 先處理 $match 管道,獲取分數在70~90之間的記錄,然后處理 $group 管道,計算和數
db.articles.aggregate( [
{ $match : { score : { $gt : 70, $lte : 90 } } },
{ $group: { _id: null, count: { $sum: 1 } } }
] );