天天看點

MongoDB開發學習(2)--文檔操作、查詢和遊标

一、文檔基本操作

目錄:

1、Document資料插入

2、Document資料删除

3、Document資料更新

1、Document資料插入

1.1插入文檔(insert)

db.[documentName].insert({})

1.2批量插入文檔

shell不支援批量插入,db.[documentName].insert([{},{},{}…])是錯誤的。

想完成批量插入文檔可以使用mongo的應用驅動或是shell的for循環。隻有插入多個文檔到一個集合時可以使用,不支援批量插入一次性對多個文檔執行批量插入操作。

1.3save操作

等同于insert()操作,差別在于:如果插入的集合的“_id”值,在集合中已經存在,用Insert執行插入操作回報異常,已經存在”_id”的鍵。用Save如果系統中沒有相同的”_id”就執行插入操作,有的話就執行覆寫掉原來的值,相當于修改操作。

2、Document資料删除

2.1删除清單中所有資料

db.[documentName].remove()

集合的本身和索引不會被删除。

2.2根據條件删除

db.[documentName].remove({})

例如:删除persons集合中name鍵等于”zhangsan”的記錄,db.persons.remove({name:”zhangsan”})

2.3小技巧

如果想删除一個資料量十分龐大的集合,可以直接删除該集合(db.drop_collection(“documentName”))并且重建立立索引的方法,效率要比remove效率高很多。

3、Document資料更新

3.1強硬的文檔替換式更新操作

db.[documentName].update({查詢器},{修改器})

此更新方法會用新的文檔代替老的文檔,但是主鍵沖突時會報錯并停止更新操作。

3.2使用修改器完成局部更新操作

通常文檔隻有一部分需要更新,此時可以考慮使用更新修改器($)。更新修改器是種特殊的鍵,用來指定複雜的更新操作,如調整、增加或删除,還可以操作數組或者内嵌文檔。

注意:使用修改器時,”_id”的值不能改變。

MongoDB開發學習(2)--文檔操作、查詢和遊标

3.3insertOrupdate操作

db.[documentName].update({查詢器},{修改器},true)

此方法的目的是查出來資料就執行更新操作,查不出來就執行替換操作

3.4批量更新操作

db.[documentName].update({查詢器},{修改器},false,true)

預設情況下當查詢出來多天資料的時候就預設修改第一條資料,但是執行此方法可以顯現批量修改。

3.5 addToSet與  each結合完成批量數組更新

db.persons.update({_id:},{$addToSet:{books:{$each:["JS","JAVA"]}}})
           

each會循環後面每一個數組吧每一個數組進行  addToSet操作。

3.6存在配置設定和查詢效率

當document被建立時,DB為其配置設定了記憶體和預留記憶體,當修改操作不超過預留記憶體的時候查詢效率非常快,當修改操作超過了預留記憶體時就要配置設定新的記憶體,此時就會比較耗費時間。

3.7runCommand函數和findAndModify函數

runCommand可以執行MongoDB中的特殊函數,findAndModify就是特殊函數之一,用于傳回update或remove後的文檔。舉例略。

二、 Find查詢

目錄

1、Find詳講

2、分頁和排序

3、遊标和其他知識

1、Find詳講

db.[documentName].find({查詢條件},{鍵指定})

查詢所有資料的指定鍵(name,age,country): db.persons.find({},{name:1,age:1,country:1,_id}:0})

1.1查詢條件

查詢出年齡在25和27歲之間的學生

db.persons.find({age:{$gte:,$lte:}},{_id:,age:})
           

1.2包含和不包含

查詢國籍是美國或中國的學生資訊

db.persons.find({country:{$in:["China","USA"]}})
           

1.3or查詢

查詢英語成績大于85或國文成績大于90的學生資訊

db.persons.find({$or:[{e:{$gte:}},{c:{$gte:}}]},{_id:,c:,e:})
           

1.4null

把中國國籍的學生加上新的鍵”sex”

db.persons.update({country:"China"},{$set:{sex:"M"}},false,true)
           

查詢出sex等于null的學生

db.persons.find({sex:{$in:[null]}},{_id:,name:,sex:})
           

1.5正則查詢

查詢出名字中存在”li”的學生的資訊

db.persons.find({name:/li/i},{_id:,name:})
           

1.6not的使用

與in不同處:not可以用到任何地方進行取反操作

查詢出名字中不存在”li”的學生資訊

db.persons.find({name:{$not:/li/i}},{name:,_id:})
           

1.7數組查詢$all和index的查詢

查詢出喜歡看”MongoDB”和”JS”的學生的資訊

db.persons.find({books:{$all:["MongoDB","JS"]}},{name:,books:,_id:})
           

查詢第二本書是”JS”的學生的資訊

db.persons.find({"books.1":"JS"},{_id:,name:})
           

1.8查詢指定長度數組$size,但它不能與比較查詢運算符一起使用,這是弊端

查詢出書籍數量大于4本的學生的資訊

db.persons.find({books:{$size:}},{_id:,name:})
           

1.9查詢出喜歡的書籍數量大于3本的學生的資訊

1)增加字段size

2)改變書籍的更新方式,每次增加書籍的時候size增加1

db.persons.update({查詢器},{$push:{books:"oracle"},$inc:{size:}})
           

3)利用$gt查詢

db.persons.find({size:{$gt:}})
           

1.10利用shell查詢出Jim喜歡看的書的數量

var Jim = db.persons.find({name:"Jim"})
while(persons.hasNext())
{
obj = persons.next();
print(obj.books.length);
}
           

1.11$slice操作符傳回文檔中指定數組内部值

查詢出Jim書架中第2-4本書

db.persons.find({name:"Jim"},{books:{$slice:[,]}})
           

查詢出Jim書架中最後一本書

db.persons.find({name:"Jim"},{books:{$slice:-}})
           

1.12文檔查詢

查詢出在K學校上過學的學生

1)用絕對比對可以完成,但是有問題(如順序之類的)

db.persons.find({school:{school:"K",score:"A"}},{_id:,name:})
           

2)為了解決順序問題我們可以使用”對象.”的方式定位

db.persons.find({"school.score":"A","school.school":"K"},{_id:,name:})
           

3)正确的解法:單條條件組查詢$elemMatch

db.persons.find({school:{$elemMatch:{school:"K",score:"A"}}})
           

1.13where

當鍵/值對查詢方式無法依然表達需求時,可是考慮使用”$where”萬能字句,它可以執行任意JavaScript作為查詢的一部分。該查詢幾乎能做任何事情。

舉例略。

2、分頁和排序

2.1 limit傳回指定資料條數

查詢出文檔中前5條資料

db.persons.find({},{_id:,name:}).limit(5)
           

2.2skip傳回指定資料的跨度

查詢出文檔中第5-10條資料

db.persons.find({},{_id:,name:}).limit(5).skip(5)
           

2.3sort傳回按照年齡排序的資料[1,-1]

db.persons.find({},{_id:,name:,age:}).sort({age:})
           

注意:MongoDB中的key可以是不同類型的資料排序也就是優先級

排序順序:最小值->null->數字(整數、長整型、雙精度)->字元串->對象/文檔->數組->二進制資料->對象ID->布爾型->日期型->時間戳->正規表達式->最大值

2.4limit和skip完成分頁

三個資料為一頁進行分頁

第一頁: db.persons.find({},{_id:0,name:1}).limit(3).skip(0)

第二頁: db.persons.find({},{_id:0,name:1}).limit(3).skip(3)

但是使用skip進行分頁時會有性能問題,當資料量非常大時,我們嘗試使用date重構文檔結構,即每次查詢操作時,前台傳值将上次最後一個文檔的日期儲存下來。

db.persons.find({date:{$gt:日期數值}}).limit(3)

個人建議:應該将軟體的重點放在便捷和精确查詢上而不是分頁性能上,因為使用者翻查最多不會2頁。

3、遊标和其他知識

3.1遊标

利用遊标周遊查詢資料

var persons = db.persons.find();
while(persons.hasNext())
{
    obj = persons.next();
    print(obj.name);
}
           

persons.hasNext()檢查是否有後續結果存在,然後用persons.next()将其獲得。

3.2遊标的幾個銷毀條件

1)用戶端發來消息将其銷毀;

2)遊标疊代完畢;

3)預設遊标超過10分鐘沒有用則會自動清除。

3.3查詢快照

快照後就會針對不變的集合進行遊标運動。所有傳回一組結果的查詢實際上都進行了快照,不一緻隻在遊标等待結果時集合内容被改變的情況下發生。

db.persons.find({$query:{name:"Jim"},$snapshot:true})
           

3.4進階查詢選項

$query
$orderby
$maxscan:integer  //指定查詢最多掃描的文檔數量
$min:document  //查詢的開始條件
$max:document  //查詢的結束條件
$hint:document  //指定伺服器使用哪個索引進行查詢
$explain:boolean  //擷取查詢執行的細節(用到的索引、結果數量、耗時),而非真正執行查詢
$snapshot:boolean  //確定查詢結果是在查詢執行的那一刻的一緻快照。
           

注意:

1、mongodb是Nosql資料庫,它在文檔查詢上功能很強大;

2、查詢符基本上放在花括号裡面,更新符基本上放在花括号外面;

3、shell是個徹底的JS引擎,但是一些特殊的操作要靠它的各個驅動包來完成,如java,node.js