MongoDB 學習筆記

MongoDB

1.簡介

概念
No 關係型數據庫 NoSQL數據庫
1 數據庫 數據庫(相似MySQL)
2 集合
3 文檔
4 成員
5 主鍵 ObjectID(自動維護)

​ MogoDB是一款強大、靈活且易於拓展的通用型數據庫。它能拓展出很是多的功能,好比二級索引、返回查詢、排序、聚合,以及地理空間索引。javascript

1.1 易於使用

​ MongoDB是一個面向文檔的數據庫,不是關係型數據庫。文檔中的鍵和值再也不是固定的類型和大小。java

1.2 易於拓展

​ 業務數據增加到必定程度時須要拓展數據庫,有兩種方式能夠進行拓展:sql

  1. 縱向擴展。使用性能更強的機器
  2. 橫向擴展。將數據分區到不一樣的機器上

​ MongoDB採用橫向拓展的方式。面向文檔的數據模型使它很容易在多臺服務器之間進行數據分割。MongoDB可以自動處理跨集羣的數據和負載,自動從新分配文檔,以及將用戶請求分配到正確的機器上。mongodb

1.3 功能豐富

MongoDB具備如下功能:數據庫

  • 索引json

    MongoDB支持二級索引,容許多種快速查詢,提供惟一索引、複合索引、地理空間索引,以及全文索引。數組

  • 聚合緩存

    MongoDB支持「聚合管道」。用戶可以經過簡單的片斷建立複雜的聚合,並經過數據庫自動優化。服務器

  • 特殊的集合類型session

    MongoDB支持存在時間有限的集合,適用於那些將在某個時刻國企的數據,如會話(session)。MongoDB也支持固定大小的集合,用於保存近期數據,如日誌。

  • 文件存儲

    MongoDB支持一種很是易用的協議,用於存儲大文件和文件元數據。

    MongoDB不具有一些關係型數據庫很廣泛的功能,如鏈接和複雜多行事務。

1.4 卓越的性能

​ MongoDB的一個主要目標是提供卓越的性能。MongoDB能對文檔動態填充,也能預分配數據文件以利用額外的空間換區穩定的性能。MongoDB把儘量多的內存用做緩存,試圖爲每次查詢自動選擇正確的索引。

MongoDB 安裝

  1. 下載

  2. 配置MongoDB環境變量

    D:\devTools\MongoDB\Server\4.0\bin

  3. 配置文件存儲路徑

    安裝目錄下新建一個data目錄

  4. 修改配置信息

    D:\devTools\MongoDB 目錄下創建mongodb.conf

    dbpath=

  5. 是的

2. MongoDB基礎知識

2.1 文檔

文檔是MongoDB的核心概念。文檔就是鍵值對的一個有序集。好比

{"greeting": "hello world!"}

這個文檔只有一個鍵「greeting,其對應的值爲」hello world! "。

文檔的鍵是字符串。除了少數例外狀況,鍵可使用任意UTF-8字符。

  • 鍵不能含有\0 (空字符)。這個字符用於表示鍵的結尾。
  • .和$具備特殊意義,只能在特定的環境下使用。這兩個字符被保留,不能使用。

MongoDB不區分類型,但區分大小寫

{"foo": 3}和{"foo":"3"}是相同的
{"foo":3}和{"Foo":3}是不一樣的

MongoDB中不能有重複的鍵

2.2 集合

集合是動態模式的。這意味着集合裏面的文檔能夠是各式各樣的。下面兩個文檔能夠放在同一個集合裏:

{"greeting": "hello, world!"}
{"foo": 5}

文檔裏面的值的類型能夠不一樣,鍵的類型也能夠不一樣

那爲何還要使用多個集合呢?

  • 不一樣的文檔放在同一個集合不利於管理。返回數據時類型混亂等。
  • 同種類型放在一個集合裏,數據更加集中,比混合在一個集合查詢更快。
  • 建立索引時,索引是按照集合類型來定義的。
2.3 命名

集合使用名稱進行標識。集合名須要知足下列條件任意的UTF-8字符串。

  • 集合名不能是空字符串("")。
  • 集合名不能不能包含\0(空字符),這個字符標識集合名的結束。
  • 集合名不能以「system.」開頭,這是爲系統集合保留的前綴
  • 用戶建立的集合不能再集合名中包含保留字‘$’。由於某些系統生成的集合中包含$。

子集合

組織集合的一種慣例是使用「.」分割不一樣命名空間的子集合。例如一個具備博客功能的應用可能包含兩個集合,分別是blog.posts和blog.authors。這是爲了使組織結構更清晰,這裏的blog集合跟他的子集合是沒有任何關係的。

2.4 數據庫

MongoDB中,多個文檔組成集合,而多個集合能夠組成數據庫。一個MongoDB能夠承載多個數據庫,每一個數據庫擁有0個或多個集合。每一個數據庫都有獨立的權限。

數據庫名需知足如下任意UTF-8的字符串

  • 不能是空字符串("")
  • 不能包含 /  . " * < > : | ? $ \0 .只是用字母和數字
  • 數據庫名區分大小寫。建議所有小寫
  • 數據庫名最多64個字節

數據庫最終會變成文件系統中的一個文件,數據庫名即對應的文件名,這也是數據庫名有諸多限制的緣由。

admin、local、config 這些數據庫名是保留的。

數據庫名+集合名=命名空間

2.5 啓動MongoDB

mongodb命令

啓動並指定數據庫

mongod --dbpath  d:/devtools/mongodb.db

啓動並指定數據庫和端口號

mongod --dbpath  d:/devtools/mongodb.db --port=77777

查看數據庫

show database

啓動並制定配置文件

mongod -f d:/devtools/mongodb/mongodb.conf

使用指定數據庫

use db1

1.帶條件刪除

db.user.remove({"name":"zhangshan"});

2.刪除全部數據

db.user.remove({})

3.刪除集合

db.user.drop()

4.刪除整個數據庫

show dbs;
db.user.getDB()
db.dropDatabase()

數據庫操做

新增

db.infos.insert({"url":"www.hanggle.com"})
db.infos.insert([{"url":"www.hanggle.com"}, {"url":"www.hanggle.com"}])
for(var i=0; i<10; i++){
    db.infos.insert({"url":"www.hanggle.com-"+ i})
}

查詢

普通查詢

查詢全部

db.infos.find();

查詢url爲"www.hanggle.com"的數據

db.infos.find({"url":"www.hanggle.com"});

查詢url爲"www.hanggle.com"的數據且id不顯示

db.infos.find({"url":"www.hanggle.com"}, {"_id":0});

查詢url爲"www.hanggle.com"的數據,數據漂亮顯示

db.infos.find({"url":"www.hanggle.com"}).pretty();

關係運算查詢

$gt $gte $ne $lt $lte
大於 大於等於 不等於 小於 小於等於

查詢age>20的記錄

db.course.find({"age":{"$gt":20}}).pretty();

查詢age大於等於20的記錄

db.course.find({"age":{"$gte":20}}).pretty();

查詢age不等於20的記錄

db.course.find({"age":{"$ne":20}}).pretty();

邏輯運算

$and $or $not/$nor

查詢age大於等於18,且小於等於20的記錄

db.course.find({"age": {"$gte": 18, "$lte": 20}})

查詢age>18或score>80的記錄

db.course.find({"$or": [{"age": {"$gt":18}},{"score":{"$gt": 80}}]})

查詢age>18而且score<80的記錄

db.course.find({"$and": [{"age": {"$gt":18}},{"score":{"$lt": 80}}]})

查詢age不大於18而且score不小於80的記錄

db.course.find({"$nor": [{"age": {"$gt":18}},{"score":{"$lt": 80}}]})

查詢數組

$all
查詢全部

查詢數組中包含語文數學的記錄

db.course.find({"course": {"$all": ["語文", "數學"]}})

查詢數組中座標1的數據爲數學的記錄

db.course.find({"course.1": "數學"})

查詢數組size爲3的記錄

db.course.find({"course": {"$size":3}})

-- 有問題 查詢數組前兩條數據

db.course.find({"course": {"$slice": 2}})

-- 有問題 查詢數組後兩條數據

db.course.find({"course": {"$slice": 2}})

-- 有問題 查詢數組中index1-2座標數據兩條數據

db.course.find({"course": {"$slice": [1, 2]}})

判斷一個字段是否存在

查詢存在course的記錄

db.course.find({"course": {"$exists": true}})

查詢不存在course的記錄

db.course.find({"course": {"$exists": false}})

where 查詢

不建議使用

正則運算

  • 基礎語法:{key: 正則標記}

  • 完整語法:{key:{"$regex":正則標記, "$options":選項}}。

    對於options主要是設置正則的信息查詢的標記:

    • "i": 忽略字母大小寫
    • "m":多行查找
    • "x": 空白字符串除了被轉義的或在字符串類中意外的徹底被忽略
    • "s":匹配全部的字符(圓點、「.」),包括換行內容。

    須要注意的是:若是是直接使用(javascript),那麼只能使用i和m,而「x」和「s」必須使用$regex

模糊查詢那麼包含A的記錄

(1) db.course.find({"name": /A/i})
(2) db.course.find({"name": {"$regex":/A/i}})

模糊查詢數組那麼包含「數」的記錄

db.course.find({"course": {"$regex":/數/i}})

數據排序

按分數倒序排序(-1),正序排序(1)

db.course.find().sort({"score": -1})

天然排序 倒序排序(-1),正序排序(1)

db.course.find().sort({"$natural": 1})

刪除數據

刪除course集合

db.course.drop()

刪除集合course中url爲www.hanggle.com的數據

db.course.remove({"url":"www.hanggle.com"});

刪除course中全部數據

db.user.remove({})

分頁顯示

  • skip(n): 表示跨過多少行
  • limit(n): 取出的數據行的個數限制

按score倒序排序跳過1條取2條

db.course.find().skip(1).limit(2).sort({"score": -1})

數據更新

查詢索引

db.infos.getIndexes()

建立索引

在集合infos上的age列建立升序索引

db.infos.ensureIndex({"age":1})

使用索引

查詢age=19的數據,FETCH表示正在使用索引

db.infos.find({"age":{"$eq":19}}).explain();

1561126812376

!強制使用索引

sql加上hint() 表示強制使用索引,強制使用索引只能使用已存在的索引。

db.infos.find({"$or":[{"age":{"$eq":19}},{"name":{"$eq":"haha"}}]}).hint().explain();

刪除索引

刪除集合上age列的正序索引

db.infos.dropIndex({"age":1});

刪除所有索引

刪除infos上除_id其它的全部索引

db.infos.dropIndexes();

建立惟一索引

在infos上建立name惟一索引

db.infos.ensureIndex({"name":1},{"unique": true});

若是增長重複數據會有如下提示信息

E11000 duplicate key error collection: mydb.infos index: name_1 dup key: { : "張三" }

過時索引

過時索引用於延時自動珊瑚記錄的一種索引。它僅包含一個字段,改字段爲Date類型,而且不支持複合索引。能夠指定某條記錄在延時固定時間後自動刪除。數據自動超時刪除主要用在系統生成的事件、日誌或者會話信息等不須要永久存儲的數據。超時時間是不許確的

  • 注意事項
  1. TTL索引僅支持一個字段,不能支持複合索引。
  2. _id字段不支持TTL索引。
  3. 不能再固定大小的集合上建立TTL索引。
  4. 不能經過createIndex()接口來改變expireAfterSeconds的值,能夠經過"collMod"命令,或者先刪除再建立的方式。
  5. 不能在已經創建索引的字段建立TTL索引。

在phone的time字段上設置過時索引,過時時間爲10s

db.phones.ensureIndex({"time":1}, {expireAfterSeconds:10});

全文索引

聚合-取得集合數量

統計info中數據個數,count能夠加參數

db.infos.count();

聚合-消除重複數據

查詢course中name去重數據

db.runCommand({"distinct":"course","key":"name"})

聚合-分組

 

聚合框架

group

Group查詢都是無序的

db.emps.insert({"name":"AAA", "dept":"部門A", "tel":110, "salery":2000, "sex":"W"});
db.emps.insert({"name":"BBB", "dept":"部門A", "tel":120, "salery":7000, "sex":"M"});
db.emps.insert({"name":"CCC", "dept":"部門B", "tel":130, "salery":4000, "sex":"W"});
db.emps.insert({"name":"DDD", "dept":"部門B", "tel":140, "salery":1000, "sex":"M"});
db.emps.insert({"name":"EEE", "dept":"部門B", "tel":150, "salery":2000, "sex":"W"});

查詢emps每一個部分的人數

db.emps.aggregate([{"$group":{"_id":"$dept", emp_count:{"$sum": 1}}}]);

查詢每一個部門總工資

db.emps.aggregate([{"$group":{"_id":"$dept", salery_count:{"$sum": "$salery"}}}]);

查詢每一個人的平均工資

db.emps.aggregate([{"$group":{
    "_id":"$dept", 
    salery_sum:{"$sum": "$salery"},
    salery_avg:{"$avg": "$salery"}
    }}]);

查詢每一個分組的數據

db.emps.aggregate([{"$group":{
    "_id":"$dept", 
    sal_data:{"$push": "$salery"}
    }}]);

查詢每一個分組最大值和最小值

db.emps.aggregate([{"$group":{
    "_id":"$dept", 
    sal_data:{"$push": "$salery"}
    }}]);

project

控制_id列不顯示,name列顯示

db.emps.aggregate([{"$project":{
    "_id":0,
    "name":1}}]);

project使用的是數據庫投影機制,投影過程當中也能夠進行加減乘除運算,

乘法運算:

db.emps.aggregate([{"$project":{
    "_id":0,
    "name":1,
    "salery":{
        "年薪":{"$multiply":["$salery",12]}
        }}}])

用戶管理

MongoDB默認不使用用戶名密碼,使用密碼要具有如下條件:

  1. 服務器啓動時打開受權認證
  2. 設置用戶名密碼

建立用戶

db.createUser({
    "user":"hanggle",
    "pwd":"hanggle",
    "roles":[{"role":"readWrite", "db":"mydb"}]
    })

修改密碼

db.changeUserPassword("mongodb", "mongodb")

配置開啓權限認證

相關文章
相關標籤/搜索