MongoDB--基礎篇

MongoDB相關概念

業務應用場景

傳統的關係型數據庫(如MySQL),在數據操做的「三高」需求以及應對Web2.0的網站需求面前,顯得力不從心。前端

解釋:「三高」需求:linux

  • High performance - 對數據庫高併發讀寫的需求。
  • Huge Storage - 對海量數據的高效率存儲和訪問的需求。
  • High Scalability && High Availability- 對數據庫的高可擴展性和高可用性的需求。

而MongoDB可應對「三高」需求。正則表達式

具體的應用場景如:sql

1)社交場景,使用 MongoDB 存儲存儲用戶信息,以及用戶發表的朋友圈信息,經過地理位置索引實現附近的人、地點等功能。mongodb

2)遊戲場景,使用 MongoDB 存儲遊戲用戶信息,用戶的裝備、積分等直接之內嵌文檔的形式存儲,方便查詢、高效率存儲和訪問。shell

3)物流場景,使用 MongoDB 存儲訂單信息,訂單狀態在運送過程當中會不斷更新,以MongoDB內嵌數組的形式來存儲,一次查詢就能將數據庫

訂單全部的變動讀取出來。express

4)物聯網場景,使用 MongoDB 存儲全部接入的智能設備信息,以及設備彙報的日誌信息,並對這些信息進行多維度的分析。json

5)視頻直播,使用MongoDB存儲用戶信息、點贊互動信息等。vim

 

這些應用場景中,數據操做方面的共同特色是:

(1)數據量大

(2)寫入操做頻繁(讀寫都很頻繁)

(3)價值較低的數據,對事務性要求不高

對於這樣的數據,咱們更適合使用MongoDB來實現數據的存儲。

📝 何時選擇MongoDB

在架構選型上,除了上述的三個特色外,若是你還猶豫是否要選擇它?能夠考慮如下的一些問題:

應用不須要事務及複雜join支持

新應用,需求會變,數據模型沒法肯定,想快速迭代開發

應用須要2000-3000以上的讀寫QPS(更高也能夠)

應用須要TB甚至 PB 級別數據存儲

應用發展迅速,須要能快速水平擴展

應用要求存儲的數據不丟失

應用須要99.999%高可用

應用須要大量的地理位置查詢、文本查詢

若是上述有1個符合,能夠考慮 MongoDB,2個及以上的符合,選擇 MongoDB 毫不會後悔。

 

MongoDB簡介

MongoDB是一個開源、高性能、無模式的文檔型數據庫,當初的設計就是用於簡化開發和方便擴展,是NoSQL數據庫產品中的一種。是最像關係型數據庫(MySQL)的非關係型數據庫。

它支持的數據結構很是鬆散,是一種相似於JSON的 格式叫BSON,因此它既能夠存儲比較複雜的數據類型,又至關的靈活。

MongoDB中的記錄是一個文檔,它是一個由字段和值對(fifield:value)組成的數據結構。MongoDB文檔相似於JSON對象,即一個文檔認爲就是一個對象。字段的數據類型是字符型,它的值除了使用基本的一些類型外,還能夠包括其餘文檔、普通數組和文檔數組。

 

體系結構

📝 MySQL和MongoDB的對比:

SQL術語概念 MongoDB術語/概念 解釋/說明
database database 數據庫
table collection 數據庫表/集合
row document 數據記錄行/文檔
column field 數據字段/域
index index 索引
table joins 錶鏈接,MongoDB不支持
嵌入文檔 MongoDB經過嵌入式文檔來替代多表鏈接
primary key primary key 主鍵,MongoDB自動將_id字段設置爲主鍵

 

數據模型

MongoDB的最小存儲單位就是文檔(document)對象,文檔(document)對象對應於關係型數據庫的行。數據在MongoDB中已BSON(Binary-JSON)文檔的格式存儲在磁盤上。

BSON(Binary Serialized Document Format)是一種類json的一種二進制形式的存儲格式,簡稱Binary JSONBSONJSON同樣,支持內嵌的文檔對象和數組對象,可是BSONJSON沒有的一些數據類型,如DateBinData類型。

Bson中,除了基本的JSON類型:string,integer,boolean,double,null,array和object,mongo還使用了特殊的數據類型。這些類型包括date,object id,binary data,regular expression 和code。每個驅動都以特定語言的方式實現了這些類型,查看你的驅動的文檔來獲取詳細信息。

BSON數據類型參考列表:

數據類型 描述 舉例
字符串 UTF-8字符串均可表示爲字符串類型的數據 {"X":"foobar"}
對象id 對象id是文檔的12字節的惟一ID {"X" :ObjectId() }
布爾值 真或者假:true或者false {"x":true}+
數組 值的集合或者列表能夠表示成數組 {"x" : ["a", "b", "c"]}
32位整數 類型不可用。JavaScript僅支持64位浮點數,因此32位整數會被自動轉換 shell是不支持該類型的,shell中默認會轉換成64位浮點數
64位整數 不支持這個類型。shell會使用一個特殊的內嵌文檔來顯示64位整數 shell是不支持該類型的,shell中默認會轉換成64位浮點數
64位浮點數 shell中的數字就是這一種類型 {"x":3.14159,"y":3}
null 表示空值或者未定義的對象 {"x":null}
undefifined 文檔中也可使用未定義類型 {"x":undefifined}
符號 shell不支持,shell會將數據庫中的符號類型的數據自動轉換成字符串
正則表達式 文檔中能夠包含正則表達式,採用JavaScript的正則表達式語法 {"x" : /foobar/i}
代碼 文檔中還能夠包含JavaScript代碼 {"x" : function() { /* …… */ }}
二進制數據 二進制數據能夠由任意字節的串組成,不過shell中沒法使用
最大值/最小值 BSON包括一個特殊類型,表示可能的最大值。shell中沒有這個類型

提示:

shell默認使用64位浮點型數值。{「x」:3.14}或{「x」:3}。對於整型值,可使用NumberInt(4字節符號整數)或NumberLong(8字節符號整數),{「x」:NumberInt(「3」)}{「x」:NumberLong(「3」)}

 

MongoDB的特色

  • 高性能:

    MongoDB提供高性能的數據持久性。特別是,

    對嵌入式數據模型的支持減小了數據庫系統上的I/O活動。

    索引支持更快的查詢,而且能夠包含來自嵌入式文檔和數組的鍵。(文本索引解決搜索的需求、TTL索引解決歷史數據自動過時的需求、地理位置索引可用於構建各類 O2O 應用)

    mmapv一、wiredtiger、mongorocks(rocksdb)、in-memory 等多引擎支持知足各類場景需求。

    Gridfs解決文件存儲的需求。

  • 高可用性:

    MongoDB的複製工具稱爲副本集(replica set),它可提供自動故障轉移和數據冗餘。

  • 高擴展性:

    MongoDB提供了水平可擴展性做爲其核心功能的一部分。

    分片將數據分佈在一組集羣的機器上。(海量數據存儲,服務能力水平擴展)

    從3.4開始,MongoDB支持基於片鍵建立數據區域。在一個平衡的集羣中,MongoDB將一個區域所覆蓋的讀寫只定向到該區域內的那些片。

  • 豐富的查詢支持:

    MongoDB支持豐富的查詢語言,支持讀和寫操做(CRUD),好比數據聚合、文本搜索和地理空間查詢等。

  • 其餘特色:

    如無模式(動態模式)、靈活的文檔模型、

 

MongoDB中的基本概念

📝 數據庫

  • 一個mongodb中能夠創建多個數據庫。
  • MongoDB的默認數據庫爲"db",該數據庫存儲在data目錄中
  • MongoDB的單個實例能夠容納多個獨立的數據庫,每個都有本身的集合和權限,不一樣的數據庫也放置在不一樣的文件中。

📝 集合

  • 集合就是MongoDB文檔組,相似於RDBMS(關係數據庫管理系統:Relational Database Management System)中的表格。
  • 集合存在於數據庫中,集合沒有固定的結構,對集合能夠插入不一樣格式和類型的數據,但一般狀況下咱們插入集合的數據都會有必定的關聯性。

集合命名的時候應該注意:

  • 集合名不能是空字符串""。
  • 集合名不能含有\0字符(空字符),這個字符表示集合名的結尾。
  • 集合名不能以"system."開頭,這是爲系統集合保留的前綴。
  • 用戶建立的集合名字不能含有保留字符。

📝 文檔(document)

是一組鍵值(key-value)對(即BSON)。MongoDB的文檔不須要設置相同的字段,而且相同的字段不須要相同的數據類型,這與關係型數據庫有很大的區別,也是MongoDB很是突出的特色。

須要注意的是:

  • 文檔中的鍵/值對是有序的。
  • 文檔中的值不只能夠是在雙引號裏面的字符串,還能夠是其餘幾種數據類型。
  • MongoDB區分類型和大小寫。
  • MongoDB的文檔不能有重複的鍵。
  • 文檔的鍵是字符串。

 

MongoDB部署

1.下載軟件包

# wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.4.1.tgz

2.解壓縮

# tar -xvzf mongodb-linux-x86_64-rhel70-4.4.1.tgz
# mv mongodb-linux-x86_64-rhel70-4.4.1 /usr/local/mongodb

3.建立數據目錄、日誌目錄、配置文件存放目錄

# mkdir /usr/local/mongodb/{data,conf,log}

4.編輯配置文件

# cat >>/usr/local/mongodb/conf/mongodb.conf<<EOF
dbpath=/usr/local/mongodb/data
logpath=/usr/local/mongodb/log/mongodb.log
bind_ip=0.0.0.0
port=27017
logappend=1
fork=1
EOF

5.添加環境變量

# vim /etc/profile
export MONGODB_HOME=/usr/local/mongodb
export PATH=$PATH:$MONGODB_HOME/bin
# source /etc/profile

6.啓動

# mongod --config /usr/local/mongodb/conf/mongodb.conf
# ps -ef |grep mongo
root     3969694       1  0 10:19 ?        00:01:06 mongod --config /usr/local/mongodb/conf/mongodb.conf

✏️ 中止mongodb

中止服務的方式有兩種:快速關閉和標準關閉
1.快速關閉方法(快速,簡單,數據可能會出錯)
目標:經過系統的kill命令直接殺死進程,殺完要檢查一下,避免有的沒有殺掉。
經過進程編號關閉節點 
# kill -2 3969694

2.標準的關閉方法(數據不容易出錯,但麻煩)
目標:經過mongo客戶端中的shutdownServer命令來關閉服務
//客戶端登陸服務,注意,這裏經過localhost登陸,若是須要遠程登陸,必須先登陸認證才行。
> mongo --port 27017 
//#切換到admin庫 
> use admin 
//關閉服務 
> db.shutdownServer()

補充

若是一旦是由於數據損壞,則須要進行以下操做(瞭解):

1.刪除lock文件

# rm -f /usr/local/mongodb/data/mongod.lock

2.修復數據

# mongod --repair --dbpath=/usr/local/mongodb/data/

 

經常使用命令

MongoDB庫操做

📝 MongoDB系統保留庫說明:

系統保留數據庫:能夠直接訪問這些有特殊做用的數據庫。

  • admin:從權限的角度來看,這是"root"數據庫
  • local:這個數據永遠不會被複制,能夠用來存儲限於本地單臺服務器的任意集合;
  • config:當Mongo用於分片設置時,config數據庫在內部使用,用於保存分片的相關信息。

✏️ 選擇和建立數據庫

> use 數據庫名

若是數據庫不存在,則建立數據庫,不然切換到指定的數據庫。

> use articledb

✏️ 查看當前服務器的全部數據庫

> show databases
或
> show dbs

✏️ 查看當前正在使用的數據庫

> db

✏️ 刪除數據庫

> db.dropDatabase()

備註:主要用來刪除已經持久化的數據庫

注意: 要刪除哪一個數據庫,必定要先切換到要刪除的數據庫中,而後再進行db.dropDatabase()

 

MongoDB集合操做

✏️ 集合的顯示建立

基本語法:

> db.createCollection(name, options)

其中
- name:要建立的集合名稱
- options:可選參數,指定有關內存大小及索引的選項(一下爲可選參數列表)

options參數以下:

字段 類型 描述
capped 布爾 (可選)若是爲true,則建立固定集合,固定集合是指有着固定大小的集合,當達到最大值時,它會自動覆蓋最先的文檔。當改值爲true時,必須指定size參數。
autoIndexld 布爾 (可選)若是爲true,自動在_id字段建立索引。默認爲true。
size 數值 (可選)爲固定集合指定一個最大值,以千字節計(KB)。若是capped爲true,也須要指定該字段。
max 數值 (可選)指定固定集合中包含文檔的最大值。

📝 示例

建立一個集合testcol
> db.createCollection("testcol");
{ "ok" : 1 }

//建立集合student
> db.createCollection("student");
{ "ok" : 1 }

//建立固定大小的集合,建立固定集合mycol,整個集合空間大小6142800KB,文檔最大個數爲10000個。
> db.createCollection("mycol",{capped:true,size:6142800,max:10000});
{ "ok" : 1 }
> show tables;
mycol
student
testcol

//建立固定大小的集合,建立固定集合mycol02,整個集合空間大小6142800KB,文檔最大個數爲10000個。
> db.createCollection("mycol02",{capped:true,size:6142800,max:10000, autoIndexId:true});
{
	"note" : "The autoIndexId option is deprecated and will be removed in a future release",
	"ok" : 1
}

注意MongoDB中,集合只有在內容插入後纔會建立! 就是說,建立集合(數據表)後要再插入一個文檔(記錄),集合纔會真正建立。

✏️ 集合的隱式建立

當向一個集合中插入一個文檔的時候,若是集合不存在,則會自動建立集合。

 

✏️ 集合的查看

> show collections
或者
> show tables

 

✏️ 集合的刪除

集合刪除語法格式以下:

> db.collection.drop()
或
> db.集合.drop()

若是成功刪除選定集合,則drop()方法返回true,不然返回false.

例如:要刪除testcol集合

> db.testcol.drop()
true

 

文檔基本CRUD

文檔(document)的數據結構和JSON基本同樣,全部存儲在集合中的數據都是BSON格式。

文檔的插入

✏️ 單個文檔插入

語法以下:

db.COLLECTION_NAME.insert(document)

示例:

> use testcoll
switched to db testcoll
> db.student.insert({name:"小白",age:18,sdept:"計算機系",sex:"男",createdatetime:new Date()})
WriteResult({ "nInserted" : 1 })

> db.student.find()
{ "_id" : ObjectId("5fa125ec481bd6c96002a80b"), "name" : "小白", "age" : 18, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-03T09:42:04.517Z") }

✏️ 批量文檔插入

語法以下:

db.COLLECTION_NAME.insertMany([document1, document2,...])

示例:

> db.student.insertMany(
	[
		{name:"張大仙",age:19,sdept:"計算機系",sex:"男",createdatetime:new Date()},
		{name:"李太白",age:17,sdept:"計算機系",sex:"男",createdatetime:new Date()}
	]
)

{
	"acknowledged" : true,
	"insertedIds" : [
		ObjectId("5fa255ab45dc2c9556990f3f"),
		ObjectId("5fa255ab45dc2c9556990f40")
	]
}

> db.student.find()
{ "_id" : ObjectId("5fa125ec481bd6c96002a80b"), "name" : "小白", "age" : 18, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-03T09:42:04.517Z") }
{ "_id" : ObjectId("5fa255ab45dc2c9556990f3f"), "name" : "張大仙", "age" : 19, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }
{ "_id" : ObjectId("5fa255ab45dc2c9556990f40"), "name" : "李太白", "age" : 17, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }

 

文檔的更新

語法以下:

db.COLLECTION_NAME.update(
	<query>{鍵名:值},
	<update>{$set:{鍵名:值}},
	{
	upsert:<boolean>,
	multi:<boolean>
	}
)
參數說明:
query:update的查詢條件
update:update的對象和更新的操做符$set,能夠理解爲sql update查詢內set後面的
upsert:可選,意思是,若是不存在update的記錄,是否插入。true爲插入,默認是false,不插入。
multi:可選,mongodb默認是false,只更新找到的第一條記錄,若是爲true,就把按條件查出來多條記錄所有更新。

示例:

✏️ 修改匹配的第一條記錄

> db.student.update(
	{sex:"男"},
	{$set:{sdept:"前端"}},
)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

> db.student.find()
{ "_id" : ObjectId("5fa125ec481bd6c96002a80b"), "name" : "小白", "age" : 18, "sdept" : "前端", "sex" : "男", "createdatetime" : ISODate("2020-11-03T09:42:04.517Z") }
{ "_id" : ObjectId("5fa255ab45dc2c9556990f3f"), "name" : "張大仙", "age" : 19, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }
{ "_id" : ObjectId("5fa255ab45dc2c9556990f40"), "name" : "李太白", "age" : 17, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }

✏️ 修改匹配的全部記錄

> db.student.update(
	{sex:"男"},
	{$set:{sdept:"後端"}},
	{multi:true}
)
WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 3 })

> db.student.find()
{ "_id" : ObjectId("5fa125ec481bd6c96002a80b"), "name" : "小白", "age" : 18, "sdept" : "後端", "sex" : "男", "createdatetime" : ISODate("2020-11-03T09:42:04.517Z") }
{ "_id" : ObjectId("5fa255ab45dc2c9556990f3f"), "name" : "張大仙", "age" : 19, "sdept" : "後端", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }
{ "_id" : ObjectId("5fa255ab45dc2c9556990f40"), "name" : "李太白", "age" : 17, "sdept" : "後端", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }

✏️ 匹配多個條件(同時知足)

> db.student.update(
	{sex:"男", name:"小白"},
	{$set:{sdept:"計算機系"}},
)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

> db.student.find()
{ "_id" : ObjectId("5fa125ec481bd6c96002a80b"), "name" : "小白", "age" : 18, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-03T09:42:04.517Z") }
{ "_id" : ObjectId("5fa255ab45dc2c9556990f3f"), "name" : "張大仙", "age" : 19, "sdept" : "後端", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }
{ "_id" : ObjectId("5fa255ab45dc2c9556990f40"), "name" : "李太白", "age" : 17, "sdept" : "後端", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }

✏️ 更新多個值

> db.student.update(
	{sex:"男", name:"小白"},
	{$set:{sdept:"英語系", age:22}},
)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

> db.student.find()
{ "_id" : ObjectId("5fa125ec481bd6c96002a80b"), "name" : "小白", "age" : 22, "sdept" : "英語系", "sex" : "男", "createdatetime" : ISODate("2020-11-03T09:42:04.517Z") }
{ "_id" : ObjectId("5fa255ab45dc2c9556990f3f"), "name" : "張大仙", "age" : 19, "sdept" : "後端", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }
{ "_id" : ObjectId("5fa255ab45dc2c9556990f40"), "name" : "李太白", "age" : 17, "sdept" : "後端", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }

✏️ 多個條件知足其中一個($or)

> db.student.update(
	{$or:[{sex:19}, {name:"小白"}]},
	{$set:{sdept:"數學系", age:22}},
)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

> db.student.find()
{ "_id" : ObjectId("5fa125ec481bd6c96002a80b"), "name" : "小白", "age" : 22, "sdept" : "數學系", "sex" : "男", "createdatetime" : ISODate("2020-11-03T09:42:04.517Z") }
{ "_id" : ObjectId("5fa255ab45dc2c9556990f3f"), "name" : "張大仙", "age" : 19, "sdept" : "後端", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }
{ "_id" : ObjectId("5fa255ab45dc2c9556990f40"), "name" : "李太白", "age" : 17, "sdept" : "後端", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }

 

文檔的刪除

語法以下:

db.COLLECTION_NAME.remove(
	<query>,
	{
	justOne:<boolean>
	}
)

參數說明:
query:(可選)刪除的文檔的條件,
justOne:(可選)若是設置爲true或1,則只刪除一個文檔,若是不設置該參數,或使用默認值false,則刪除全部匹配條件的文檔。

示例:

✏️ 刪除符合條件的第一條(justOne.true)

> db.student.remove(
	{sex:"男"},
	{justOne:true}
)
WriteResult({ "nRemoved" : 1 })

> db.student.find()
{ "_id" : ObjectId("5fa255ab45dc2c9556990f3f"), "name" : "張大仙", "age" : 19, "sdept" : "後端", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }
{ "_id" : ObjectId("5fa255ab45dc2c9556990f40"), "name" : "李太白", "age" : 17, "sdept" : "後端", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }

✏️ 刪除符合條件的全部記錄

> db.student.remove(
	{sex:"男"}
)

✏️ 刪除全部記錄

> db.student.remove({})

 

文檔的查詢

MongoDB查詢文檔使用find()方法,使用findOne()查詢一條數據

find()方法以非結構化的方式來顯示全部的文檔

語法格式:

db.COLLECTION_NAME.find(query,projection)

注意:
query:可選,使用查詢操做符指定查詢條件
projection:可選,使用投影操做符指定返回的值
須要以格式化的方式來讀取數據,可使用pretty()方法。

查詢前先造幾條數據

db.student.insertMany(
	[
		{name:"張大仙",age:19,sdept:"計算機系",sex:"男",createdatetime:new Date()},
		{name:"李太白",age:17,sdept:"計算機系",sex:"男",createdatetime:new Date()},
		{name:"黃花",age:18,sdept:"英語系",sex:"女",createdatetime:new Date()},
		{name:"菜花",age:20,sdept:"數學系",sex:"女",createdatetime:new Date()},
	]
)

基本查詢

✏️ 查詢student集合中全部的文檔

> db.student.find()
{ "_id" : ObjectId("5fa27688b808fba58f5a3a41"), "name" : "張大仙", "age" : 19, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T09:38:16.820Z") }
{ "_id" : ObjectId("5fa27688b808fba58f5a3a42"), "name" : "李太白", "age" : 17, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T09:38:16.820Z") }
{ "_id" : ObjectId("5fa27688b808fba58f5a3a43"), "name" : "黃花", "age" : 18, "sdept" : "英語系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T09:38:16.820Z") }
{ "_id" : ObjectId("5fa27688b808fba58f5a3a44"), "name" : "菜花", "age" : 20, "sdept" : "數學系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T09:38:16.820Z") }

✏️ 格式化方法顯示查詢結果

> db.student.find().pretty()
{
	"_id" : ObjectId("5fa27688b808fba58f5a3a41"),
	"name" : "張大仙",
	"age" : 19,
	"sdept" : "計算機系",
	"sex" : "男",
	"createdatetime" : ISODate("2020-11-04T09:38:16.820Z")
}
{
	"_id" : ObjectId("5fa27688b808fba58f5a3a42"),
	"name" : "李太白",
	"age" : 17,
	"sdept" : "計算機系",
	"sex" : "男",
	"createdatetime" : ISODate("2020-11-04T09:38:16.820Z")
}
{
	"_id" : ObjectId("5fa27688b808fba58f5a3a43"),
	"name" : "黃花",
	"age" : 18,
	"sdept" : "英語系",
	"sex" : "女",
	"createdatetime" : ISODate("2020-11-04T09:38:16.820Z")
}
{
	"_id" : ObjectId("5fa27688b808fba58f5a3a44"),
	"name" : "菜花",
	"age" : 20,
	"sdept" : "數學系",
	"sex" : "女",
	"createdatetime" : ISODate("2020-11-04T09:38:16.820Z")
}

✏️ 條件過濾查詢

> db.student.find({sex:"男"})
{ "_id" : ObjectId("5fa27688b808fba58f5a3a41"), "name" : "張大仙", "age" : 19, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T09:38:16.820Z") }
{ "_id" : ObjectId("5fa27688b808fba58f5a3a42"), "name" : "李太白", "age" : 17, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T09:38:16.820Z") }

✏️ 查詢一條記錄

> db.student.findOne()
{
	"_id" : ObjectId("5fa27688b808fba58f5a3a41"),
	"name" : "張大仙",
	"age" : 19,
	"sdept" : "計算機系",
	"sex" : "男",
	"createdatetime" : ISODate("2020-11-04T09:38:16.820Z")
}

 

條件查詢

✏️ 多個條件同時知足查詢 $and

db.COLLECTION_NAME.find({K1:V1,K2:V2,K3:V3...})
或者
db.COLLECTION_NAME.find({$and:[{K1:V1},{K2:V2},{K3:V3}...]})

示例:

# 查詢年齡爲19,並且性別爲男的學生
> db.student.find({age:19,sex:"男"})
{ "_id" : ObjectId("5fa27688b808fba58f5a3a41"), "name" : "張大仙", "age" : 19, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T09:38:16.820Z") }

> db.student.find({$and:[{age:19},{sex:"男"}]})
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4b"), "name" : "張大仙", "age" : 19, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }

✏️ 多個條件只是知足其中一個 $or

db.COLLECTION_NAME.find({$or:[{K1:V1},{K2:V2},{K3:V3}...]})

示例:

# 查詢年齡是19或者爲英語系的學生
> db.student.find({$or:[{age:19},{sdept:"英語系"}]})
{ "_id" : ObjectId("5fa27688b808fba58f5a3a41"), "name" : "張大仙", "age" : 19, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T09:38:16.820Z") }
{ "_id" : ObjectId("5fa27688b808fba58f5a3a43"), "name" : "黃花", "age" : 18, "sdept" : "英語系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T09:38:16.820Z") }

✏️ 根據數據類型來匹配對應的結果$type

db.COLLECTION_NAME.find({KEY:{$type:數字或者數據類型}})

$tpye操做符,MongoDB中可使用的類型以下表所示:

類型 數字 備註
Double 1
String 2
Object 3
Array 4
Binary data 5
Undefined 6 已廢棄
Object id 7
Boolean 8
Date 9
Null 10
Regular Expression 11
JavaScript 13
Symbol 14
JavaScript (with scope) 15
32-bit integer 16
Timestamp 17
64-bit integer 18
Min key 255 Query with -1
Max key 127

示例:

# 這裏先插入一條數據進行測試
> db.student.insert({name:12,age:28,sdept:"體育系",createdatetime:new Date()})
WriteResult({ "nInserted" : 1 })

# 查詢名字類型爲Double類型的學生
> db.student.find({name:{$type:1}})
{ "_id" : ObjectId("5fa36936bde0f17be2c81931"), "name" : 12, "age" : 28, "sdept" : "體育系", "createdatetime" : ISODate("2020-11-05T02:53:42.760Z") }

✏️ 讀取指定數量的數據記錄limit()

db.COLLECTION_NAME.find().limit(NUMBER)

NUMBER:表示記錄條數,默認值爲20

示例:

# 查詢性別爲男學生前2條記錄
> db.student.find({sex:"男"}).limit(1)
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4b"), "name" : "張大仙", "age" : 19, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }

✏️ 查詢出來的記錄,跳過指定數量的前多少條記錄skip()

db.COLLECTION_NAME.find().skip(NUMBER)
或者
db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)

備註:skip(NUMBER)中的NUMBER默認值爲0

示例:

# 查詢全部的性別爲男的學生信息並跳過第一條記錄
> db.student.find({sex:"男"}).skip(1)
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4c"), "name" : "李太白", "age" : 17, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }

# 查詢前兩條性別爲男的學生信息,跳過第一條記錄
> db.student.find({sex:"男"}).limit(2).skip(1)
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4c"), "name" : "李太白", "age" : 17, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }

✏️ 對查詢出來的記錄進行排序 sort()

db.COLLECTION_NAME.find().sort({key:1})
或者
db.COLLECTION_NAME.find().sort({key:-1})

備註:sort()方法能夠經過參數指定排序的字段,並使用1和-1來指定排序的方式,其中1爲升序排列,而-1爲降序排列。

示例:

# 查詢全部學生信息,按照年齡升序排列
> db.student.find().sort({age:1})
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4c"), "name" : "李太白", "age" : 17, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4d"), "name" : "黃花", "age" : 18, "sdept" : "英語系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4b"), "name" : "張大仙", "age" : 19, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4e"), "name" : "菜花", "age" : 20, "sdept" : "數學系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa36936bde0f17be2c81931"), "name" : 12, "age" : 28, "sdept" : "體育系", "createdatetime" : ISODate("2020-11-05T02:53:42.760Z") }

# 查詢全部學生信息,按照年齡降序排列
> db.student.find().sort({age:-1})
{ "_id" : ObjectId("5fa36936bde0f17be2c81931"), "name" : 12, "age" : 28, "sdept" : "體育系", "createdatetime" : ISODate("2020-11-05T02:53:42.760Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4e"), "name" : "菜花", "age" : 20, "sdept" : "數學系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4b"), "name" : "張大仙", "age" : 19, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4d"), "name" : "黃花", "age" : 18, "sdept" : "英語系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4c"), "name" : "李太白", "age" : 17, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }

 

比較查詢

✏️ 大於查詢 $gt

db.COLLECTION_NAME.find({KEY:{$gt:value}})

示例:

# 查詢年齡大於17的學生
> db.student.find({age:{$gt:17}})
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4b"), "name" : "張大仙", "age" : 19, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4d"), "name" : "黃花", "age" : 18, "sdept" : "英語系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4e"), "name" : "菜花", "age" : 20, "sdept" : "數學系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }

✏️ 小於查詢$lt

db.COLLECTION_NAME.find({KEY:{$lt:value}})

示例:

# 查詢年齡小於20的學生
> db.student.find({age:{$lt:20}})
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4b"), "name" : "張大仙", "age" : 19, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4c"), "name" : "李太白", "age" : 17, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4d"), "name" : "黃花", "age" : 18, "sdept" : "英語系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }

✏️ 大於等於查詢 $gte

db.COLLECTION_NAME.find({KEY:{$gte:value}})

示例:

# 查詢年齡大於等於17的學生
> db.student.find({age:{$gte:17}})
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4b"), "name" : "張大仙", "age" : 19, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4c"), "name" : "李太白", "age" : 17, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4d"), "name" : "黃花", "age" : 18, "sdept" : "英語系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4e"), "name" : "菜花", "age" : 20, "sdept" : "數學系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }

✏️ 小於等於查詢 $lte

db.COLLECTION_NAME.find({KEY:{$lte:value}})

示例:

# 查詢年齡小於等於20的學生
> db.student.find({age:{$lte:20}})
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4b"), "name" : "張大仙", "age" : 19, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4c"), "name" : "李太白", "age" : 17, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4d"), "name" : "黃花", "age" : 18, "sdept" : "英語系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4e"), "name" : "菜花", "age" : 20, "sdept" : "數學系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }

✏️ 不等於查詢 $ne

db.COLLECTION_NAME.find({KEY:{$ne:value}})

示例:

# 查詢年齡不等於20的學生
> db.student.find({age:{$ne:20}})
db.student.find({age:{$ne:20}})
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4b"), "name" : "張大仙", "age" : 19, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4c"), "name" : "李太白", "age" : 17, "sdept" : "計算機系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4d"), "name" : "黃花", "age" : 18, "sdept" : "英語系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }

綜合示例:

# 查詢年齡在17~19之間的學生
> db.student.find({age:{$gt:17,$lt:19}})
# 查詢年齡小於18,大於19的學生
> db.student.find({$or:[{age:{$lt:18}},{age:{$gt:19}}]})

 

聚合查詢

MongoDB中聚合(aggregate)主要用於處理數據(諸如統計平均值,求和等),並返回計算後的數據結果。

格式以下:

db.COLLECTION_NAME.aggregate([
	{
		管道:{聚合操做表達式}
	}
])

管道:就是把找到的數據進行過濾的操做,經常使用的管道符以下表

管道符 描述
$project 修改輸入文檔的結構。能夠用來重命名、增長或刪除域
$match 用於過濾數據,只輸出符合條件的文檔。$match使用MongoDB的標準查詢操做
$limit 用來限制MongoDB聚合管道返回的文檔數
$skip 在聚合管道中跳過指定數量的文檔,並返回餘下的文檔
$group 將集合中的文檔分組,可用於統計結果
$sort 將輸入文檔排序後輸出

經常使用聚合表達式

表達式 描述
$sum 計算總和
$avg 計算平均值
$min 獲取集合中全部文檔對應值的最小值
$max 獲取集合中全部文檔對應值的最大值

✏️ 分組$group

db.集合名字.aggregate([
	{
		$group:{_id:"$字段名",聚合函數的別名:{聚合表達式:"$字段名"}}
	}
])

示例:

# 統計學生信息男生和女生的總年齡
> db.student.aggregate([
	{
		$group:{_id:"$sex",成績總和:{$sum:"$age"}}
	}
])

{ "_id" : "女", "成績總和" : 38 }
{ "_id" : "男", "成績總和" : 36 }


# 統計學生信息男生和女生各有多少人
> db.student.aggregate([
	{
		$group:{_id:"$sex",總人數:{$sum:1}}
	}
])

{ "_id" : "女", "總人數" : 2 }
{ "_id" : "男", "總人數" : 2 }

//備註:$sum:1 等於MySQL的count(*) 統計總的記錄數


# 求學生的總數和平均年齡
> db.student.aggregate([
	{
		$group:{_id:null,人數:{$sum:1},平均年齡:{$avg:"$age"}}
	}
])

{ "_id" : null, "人數" : 4, "平均年齡" : 18.5 }


# 求男生或者女生的總數和平均年齡
> db.student.aggregate([
	{
		$group:{_id:"$sex",人數:{$sum:1},平均年齡:{$avg:"$age"}}
	}
])
{ "_id" : "女", "人數" : 2, "平均年齡" : 19 }
{ "_id" : "男", "人數" : 2, "平均年齡" : 18 }


# 查詢男生和女生的人數,按人數升序排列
> db.student.aggregate([
	{
		$group:{_id:"$sex",總人數:{$sum:1}}
	},
	{
		$sort:{總人數:1}
	}
])


# 查詢年齡小於等19,只看兩條記錄
> db.student.find({age:{$lte:19}}).limit(2)		#普通方法
# 管道的方法
> db.student.aggregate([
	{
		$match:{age:{$lte:19}}
	},
	{$limit:2}
])


# 查看男生的最大年齡
> db.student.aggregate([
	{
		$match:{sex:"男"}
	},
	{
		$group:{_id:"$sex", 最高分:{$max:"$age"}}
	}
])


# 修改文檔結構,只含有_id,name,age
> db.student.aggregate([
	{
		$project:{name:1,age:1}
	}
])
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4b"), "name" : "張大仙", "age" : 19 }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4c"), "name" : "李太白", "age" : 17 }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4d"), "name" : "黃花", "age" : 18 }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4e"), "name" : "菜花", "age" : 20 }
//備註:在$project,字段名:1 ---->獲取該字段的全部內容
//等於MySQL中的 select name,age from student;

 

經常使用命令總結

# 選擇切換數據庫:
use DB_NAME
# 插入數據:
db.COLLECTION_NAME.insert({bson數據})
# 查詢全部數據:
db.COLLECTION_NAME.find()
# 格式化顯示查詢的數據:
db.COLLECTION_NAME.find().pretty()
# 條件查詢數據:
db.COLLECTION_NAME.find({K1:V1,K2:V2...})
# 查詢符合條件的第一條記錄:
db.COLLECTION_NAME.findOne({K1:V1,K2:V2...})
# 查詢符合條件的前幾條記錄:
db.COLLECTION_NAME.find({K1:V1,K2:V2...}).limit(條數)
# 查詢符合條件的跳過的記錄:
db.COLLECTION_NAME.find({K1:V1,K2:V2...}).skip(條數)
# 查詢知足多個條件中任意條件的記錄:
db.COLLECTION_NAME.find({$or:[{K1:V1},{K2:V2},{K3:V3}...]})
# 對查詢結果進行升序排序
db.COLLECTION_NAME.find().sort({kEY:1})
# 對查詢結果進行降序排序
db.COLLECTION_NAME.find().sort({kEY:-1})
# 大於查詢
db.COLLECTION_NAME.find({KEY:{$gt:value}})
# 小於查詢
db.COLLECTION_NAME.find({KEY:{$lt:value}})
# 大於等於查詢
db.COLLECTION_NAME.find({KEY:{$gte:value}})
# 小於等於查詢
db.COLLECTION_NAME.find({KEY:{$lte:value}})
# 不等於查詢
db.COLLECTION_NAME.find({KEY:{$ne:value}})
# 查詢大於小於之間的數據記錄
db.COLLECTION_NAME.find({KEY:{$gt:NUMBER,$lt:NUMBER}})
# 查詢小於多少,或者大於多少的數據
db.COLLECTION_NAME.find({$or:[{KEY:{$lt:NUMBER}},{KEY:{$gt:NUMBER}}]})
# 統計查詢
db.COLLECTION_NAME.find().count()
相關文章
相關標籤/搜索