只要是數據庫那么就絕對離不開最為核心的功能: CRUD, 所以在MongoDB里面對于數據的操作也是支持的, 但是除了增加之外, 其他操作都是很麻煩的。
4.1 數據增加
- 使用 db.collection.insert() 可以實現數據的增加操作
增加一個簡單數據
db.insert({"url": "www.mldn.cn"})
如果要想保存多個數據就使用數組
范例: 保存數組
db.infos.insert([
{'url': 'www.mldn.cn'},
{'url': 'www.mldnjavascript.cn'}
])
- 如果保存多條以上數據就
范例: 保存10000個數據
for ( var i = 0 ; i < 10000 ; i++ ) {
db.infos.insert( { "url": "mldn - " + i } )
}
如果數據保存很多的情況下, 列表不會全部列出, 它只會列出部分的內容
4.2 數據查詢
任何的數據庫之中, 數據的查詢操作都是最為麻煩的, 而在MongoDB數據庫里面, 對于查詢的支持非常到位, 包含有關系運算、邏輯運算、數組運算、正則運算等
首先對于數據的查詢操作核心的語法: db.collection.find({查詢條件}, {設置顯示的字段})
范例: 最簡單的用法就是直接使用find()函數完成查詢
db.infos.find()
范例:希望查詢出url為"www.mldn.cn"的數據
db.infos.find({"url": "www.mldn.cn"})
發現在進行數據查詢的時候也是按照JSON的形式設置的相等關系.它的整個開發之中不可能離開JSON數據
對于設置的顯示字段嚴格來講究就稱為數據的投影操作, 如果不需要顯示的字段設置"0", 而需要顯示的字段設置"1"
范例: 不想顯示"_id"
db.infos.find({"url": "www.mldn.cn"}, {"_id": 0})
db.infos.find({"url":"www.mldn.cn"}, {"_id":0, "url": 1})
大部分情況下, 這種投影的意義不大. 同時對于數據的查詢也可以使用"pretty()"函數
范例: 漂亮顯示
db.infos.find({"url":"www.mldn.cn", {"_id":0,"url":1}).pretty()
數據列多的時候一定可以看出華麗的顯示效果
范例: 查詢單個數據
db.infos.findOne({"url":"www.mldn.cn"}).pretty()
利用以上的查詢可以實現數據格式化輸出效果, 前提: 列的內容必須多。
4.2.1 關系運算
在MongoDB里面支持的關系查詢操作: 大于($gt)、小于($lt)、 大于等于($gte)、小于等于($lte)、不等于($ne)、等于($eq)
范例: 定義一個學生信息集合
db.students.insert({name: '張三', sex: '男', age: 19, score: 59, address: '海淀區'})
db.students.insert({name: '李四', sex: '女', age: 20, score: 99, address: '朝陽區'})
db.students.insert({name: '王五', sex: '女', age: 19, score: 100, address: '西城區'})
db.students.insert({name: '趙六', sex: '男', age: 30, score: 20, address: '東城區'})
db.students.insert({name: '孫七', sex: '男', age: 19, score: 0, address: '海淀區'})
db.students.insert({name: '王八', sex: '女', age: 25, score: 70, address: '朝陽區'})
db.students.insert({name: '劉九', sex: '男', age: 17, score: 56, address: '海淀區'})
db.students.insert({name: '錢十', sex: '女', age: 19, score: 89, address: '西城區'})
范例: 查詢姓名是張三的學生信息
db.students.find({"name": "張三"}).pretty()
范例: 查詢性別是男的學生信息
db.students.find({"sex": "男"}).pretty()
范例: 查詢年齡大于19的學生
db.students.find("age": {"$gt": 19}).pretty()
范例: 查詢成績大于等于60分的學生
db.students.find({score:{"$gte": 60}}).pretty()
范例: 查詢姓名不是王五的信息
db.students.find("name": {"$ne": "王五"}).pretty()
此時與之前最大的區別就在于, 在一個JSON結構里面需要定義其他的JSON結構, 并且這種風格在日后通過程序進行操作的時候依然如此.
4.2.2.邏輯運算
邏輯運算主要就是三種類型: 與($and) 、或($or)、非($nor、$not)
范例: 查詢年齡在 19~20歲的學生信息
db.students.find({age:[ {"$gte": 19},{"$lte": 20}]}).pretty()
在進行邏輯運算”$and"的連接最容易, 因為只需要利用","分割若干個條件就可以了。
范例: 查詢年齡不是19歲的學生
db.students.find({"age": {"$ne": 19}}).pretty()
范例: 查詢年齡大于19歲, 或者成績大于90分的學生信息
db.students.find({"$or": [
{
"age": {"$gt": 19}
},
{
"score": {"$gt": 90}
}
]}).pretty()
范例: 也可以進行或的求反操作
db.students.find({"$nor": [
{
"age": {"$gt": 19}
},
{
"score": {"$gt": 90}
}
]}).pretty()
針對于或的求反操作可以實現一個求反的操作
在這幾個邏輯運算之中, 與的連接最簡單, 而或的連接需要為數據設置數組的過濾條件
4.2.3.求模
模的運算使用 "$mod"來完成, 語法"{"$mod": [數字, 余數]}"
范例: 求模
db.students.find({"age": {"$mod": [20, 1]}}).pretty()
4.2.4范圍查詢
只要是數據庫, 必須存在有"$in"(在范圍之中)、"$nin"( 不再范圍之中 )
范例: 查詢姓名是"張三", "李四", "王五"的信息
db.students.find({"name": {"$in": ["張三", "李四", "王五"]}).pretty()
范例: 不在范例
db.students.find({"name": {"$nin": ["張三", "李四", "王五"]}).pretty()
4.2.5數組查詢
首先在MongoBD里面是支持數組保存的, 一旦支持了數組保存, 就需要針對于數組的數據進行匹配.
范例:保存一部分數組內容
db.students.insert([
{
name: '谷大神_A',
sex: '男',
age: 19,
score: 89,
address: '海淀區',
course: ['語文', '數學', '英語', '音樂', '政治']
}])
db.students.insert([
{
name: '谷大神_B',
sex: '男',
age: 19,
score: 89,
address: '海淀區',
course: ['語文', '數學']
}])
db.students.insert([
{
name: '谷大神_A',
sex: '男',
age: 19,
score: 89,
address: '海淀區',
course: ['語文', '數學', '英語']
}])
db.students.insert([
{
name: '谷大神_A',
sex: '男',
age: 19,
score: 89,
address: '海淀區',
course: [ '英語', '音樂', '政治']
}])
db.students.insert([
{
name: '谷大神_A',
sex: '男',
age: 19,
score: 89,
address: '海淀區',
course: [ '語文', '政治']
}])
此時的數據包含有數據內容, 而后需要針對于數據數據進行判斷, 可以使用幾個運算符: $all、$slice、$size、$elemMatch
范例: 查詢同時參加語問和數學課程的學生
現在兩個數組內容都需要保存, 所以使用{$all: [內容一, 內容二, ...]}
db.students.find({"course": {"$all": ["語文","數學"]}}).pretty()
現在所有顯示的學生信息里面包含語文和數學的內容, 而如果差一個內容就不會顯示。
雖然"$all" 計算可以用于數組上, 但是也可以用于一個數據的匹配上。
范例: 查詢學生地址是"海淀區"的信息
db.students.find({"address": {"$all": ["海淀區"]}).pretty()
既然在集合里面現在保存的是數組信息,那么數組就可以利用索引操作,使用"key.index"的方法來定義索引
范例: 查詢數組中第二個內容(index = 1, 索引下標從0開始)為數學的信息
db.students.find({"course.1":"數學"}).pretty()
范例: 要求查詢出只參加2門課程的學生
使用$size來進行數量的控制
db.students.find("course: {"$size": 2}).pretty()
發現在進行數據查詢的時候只要內容符合條件, 數字的內容就全部顯示出來了, 但是現在希望可以控制數組的返回的數量, 那么可以使用"$slice"進行控制。
范例: 返回年齡為19歲所有學生的信息, 但是要求只顯示兩門參加課程.
db.students.find("age": 19, {"course": {"$slice": 2}}).pretty()
現在只取出前兩門的信息,那么也可以設置負數表示取出后兩門的信息.
db.students.find({"age": 19}, {"course": {"$slice": -2}}).pretty()
或者只是取出中間部分的信息
db.students.find({"age": 19, {"course": {"$slice: [1, 2]}}}).pretty()
在此時設置的兩個數據里面第一個數據表示跳過的數據量, 而第二個表示返回的數量
而$elemMatch操作符輸出滿足這樣條件的文檔, 即文檔中filed數據中至少一個元素滿足全部知道指定的匹配要求
db.students.insert({
resultes: [82, 85, 88, {product: 'xyz}]
})
db.students.find({"resultes": {"$elemMatch": {"$gt": 84,"$lt": 886}}).pretty()
此時85剛好滿足 全部要求
還有一種單一條件查詢
db.students.find({"resultes": {"$elemMatch": {product: 'xyz}}).pretty()
上面的例子中,因為 $elemMatch 操作符只指定一個查詢條件,那么當只有一個查詢條件時,使用 $elemMatch 操作符有點大材小用了,你可以將上面的查詢替換成下面這樣子:
db.students.find({"resultes.product":"xyz"}).pretty()
4.2.6.嵌套集合運算
在MongoDB數據里面每一個集合數據都可以繼續保存其他的集合數據, 例如: 有些學生需要保存家長信息
范例: 增加數據
db.students.drop()
db.students.insert({name: '高大拿 - A',sex: '男', age: 19, score: 89, address: '海淀區',
course: ['語文', '數學', '英語', '音樂', '政治'],
parents: [
{name: '高大拿 -A (父親)', age: 50, job: '工人'},
{name: '高大拿 -A (母親)', age: 46, job: '職員'}]})
db.students.insert({name: '高大拿 - B',sex: '男', age: 19, score: 89, address: '海淀區',
course: ['語文', '數學'],
parents: [
{name: '高大拿 -B (父親)', age: 50, job: '處長'},
{name: '高大拿 -B (母親)', age: 46, job: '局長'}]})
db.students.insert({name: '高大拿 - C',sex: '男', age: 19, score: 89, address: '海淀區',
course: ['語文', '數學', '英語'],
parents: [
{name: '高大拿 -C (父親)', age: 50, job: '工人'},
{name: '高大拿 -C (母親)', age: 46, job: '局長'}]})
此時給出的內容是嵌套的集合,而這種集合的數據的判斷只能過通過$elemMatch完成。
范例: 查詢出父母是局長的信息
db.students.find({
"$and": [
{"$gte": 19},
{"parents": {
"$elemMatch": {job: '局長”}
}}
]
}).pretty()
由于這種查詢的時候條件比較麻煩, 所以如果可能, 盡量別搞這么復雜的數據結構組成.
4.2.7. 判斷某個字段是否存在
使用"$exists"可以判斷某個字段是否存在, 如果設置為True表示存在, 如果設置為false就表示不存在.
范例: 查詢具有parents的成員的數據
db.students.find({"parents": {"$exists": true}}).pretty()
范例: 查詢不具有course成員的數據
db.students.find({"course": {$exists: false}}).pretty()
可以利用此類查詢來進行一些不需要的數據過濾.
4.2.8 條件過濾
實際上習慣于傳統關系型數據庫開發的我們對于數據的篩選, 可以首先想到的一定是where子句, 所以在MongoDB里面也提供有'$where'.
范例: 使用where進行數據查詢
db.students.find({"$where": "this.age > 20"}).pretty()
db.students.find("this.age > 20").pretty()
對于"$where"是可以簡化的, 但是這類的操作是屬于進行每一行的信息判斷, 實際上對于數據量大的情況下并不方便使用. 實際上以上的代碼嚴格來講是屬于編寫一個操作的函數
db.students.find(function() {
return this.age > 20
}).pretty()
db.students.find({"$where": function() {
return this.age > 20
}}).pretty()
以上只是查詢了一個判斷, 如果要想實現多個條件的判斷, 那么就需要使用and連接.
db.students.find({"$and": [
{"$where": "this.age > 19"},
{"$where": "this.age < 21"}
]}).pretty()
雖然這種形式的操作可以實現數據查詢, 但是最大的缺點是將在MongoDB里面保存的BSON數據變成了Javascript的語法結構, 這樣的方式不方便使用數據庫索引機制.
4.2.9 正則運算
如果要想實現模糊查詢, 那么必須使用正則表達式, 而且正則表達式使用的語言是Perl兼容的正則表達式的形式. 如果要想實現正則使用, 則按照以下的定義格式:
基礎語法: {key: 正則標記}
. 完整語法: {key: {"$regex": 正則標記, "$options": 選項}}
|- 對于options主要是設置正則的信息查詢的標記
|- 'i' : 忽略字母大小寫
|- 'm': 多行查找
|- 'x': 空白字符串除了被轉義的或在字符類中意外的完全被忽略
|- 's': 匹配所有的字符(圓點: '.'), 包括換行內容.
|-需要注意的是, 如果是直接使用(javascript )那么只能夠使用i和m, 而'x'和’s'必須使用'$regex'
范例: 查詢以 '谷'開頭的姓名
db.students.find("name": /谷/).pretty()
范例: 查詢姓名有字母A
db.students.find({"name": /a/i|).pretty()
db.students.find({"name': {"$regex": /a/i}}).pretty()
如果要執行模糊查詢的操作, 嚴格來講只需要編寫一個關鍵字就夠了
正則操作之中除了可以查詢出單個字段的內容之外, 也可以進行數組數據的查詢.
范例: 查詢數組數據
db.students.find({"course":/語?/}).pretty()
db.students.find({"course":/語/}).pretty()
MongoDB中的正則符號和之前Java正則式有一些小小差別, 不建議使用以前的一些標記.正則就將其應用在模糊數據查詢上.
4.2.10 數據排序
在 MongoDB里面數據的排序操作使用"sort"函數, 在進行排序的時候可以有兩個順序: 升序(1)、 降序(-1)
范例: 數據排序
db.students.find().sort({"score": -1}).pretty()
但是在進行排序的過程里面有一種方式稱為自然排序, 按照數據保存的先后順序排序, 使用"$natural"表示
范例: 自然排序
db.students.find().sort({"$natural": -1}).pretty()
在MongoDB數據庫里面排序的操作相比較傳統關系型數據庫的設置要簡單.
4.2.11 數據分頁顯示
在MongoDB里面的數據分頁顯示也是符合大數據要求的操作函數.
.skip(n) : 表示跨過多少數據行;
.limit(n):取出的數據行的個數限制
: 分頁顯示(第一頁, skip(0)、limit(5))
db.students.find().skip(0).limit(5).sort({"age": -1}).pretty()
范例: 分頁顯示(第二頁, skip()、limit(5))
db.students.find().skip(5).limit(5).sort({"age": -1}).pretty()
這兩個分頁的控制操作, 就是在以后只要是存在有大數據的信息情況下都會使用它.