4. 數據庫操作 4.1~4.2

只要是數據庫那么就絕對離不開最為核心的功能: 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()

這兩個分頁的控制操作, 就是在以后只要是存在有大數據的信息情況下都會使用它.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容