1. 程式人生 > 其它 >MongoDB常用sql

MongoDB常用sql

基本查詢

簡單查詢

find({"comId":"1012", "group":123})

包含:$in

find({name: {$in:["zhangsan", "lisi"]}})             #in是匹配[]中任意一個值即可
find({name: {$in:[/^zh/, /si$/]}})                   #查詢name欄位中,以zh開頭或者si結尾的
find({"procTree.pid": {$in: [2011, 2012]}})          #當欄位為一個數組時,陣列中的任一元素匹配[]中任意一個值即可

匹配所有:$all

find({"
procTree.pid": {$all: [2011, 2012]}}) #all是必須匹配[]中所有值才算匹配

範圍查詢

操作符:$gte:大於等於 $lte:小於等於 $eq:等於

find({age: {$lt:20}})     #查詢age<20的
find({age: {$gt:20}})     #查詢age>20的
find({tags: {$ne:null}})  #查詢tags不為空的

陣列中元素個數:$size

find({"procTree": {$size: 2}})    #查詢procTree陣列中有兩個元素的

模糊查詢

find({"comId
":/11/}) #查詢comId包含11的(全模糊匹配) find({"comId":/^11/}) #字首匹配 find({"comId":{$regex:"^11"}}) #字首匹配 find({"comId":{$regex:"12$", $options:"i"}}) #字尾匹配,忽略大小寫

“非”查詢:$not、$nin

$not後面只能接表示式,比如正則、$gt等

find({name: {$not: /zhang/}})               #查詢name欄位,不是以zhang開頭的
find({age: {$not: {$gt: 30}}}) #查詢age欄位,不是大於30的,即小於等於30的 find({name: {$nin: [/^zh/, /si$/]}}) #查詢name欄位,不是以zh開頭或者si結尾的 find({name: {$nin: ["zhangsan", "lisi"]}}) #查詢name欄位,既不等於zhangsan也不等於lisi的

投影查詢

find({"comId":{$regex:"12$"}, {"comId":1, "detectType":1, "group":1, "_id":0})     #1表示顯示,0表示不顯示。_id預設顯示,要不想顯示,需要設定為0

分頁查詢

find().skip(3).limit(2)            #跳過3條資料,然後返回最多2條資料

查詢資料條數:count()

find({"comId":"1012"}).count()                #返回find過濾後的資料條數
find({"comId":"1012"}).limit(2).count(true)   #返回2條資料。使用了limit的sql,如果直接使用count(),裡面引數不是true或者非0的,那返回的結果就是全部的(跟上面一樣)

排序:sort()

find({"comId":"1012"},{"group":1, "_id":0}).sort({"group":1})   #根據group排序。1是升序,-1是降序

聚合查詢

計數、求和:$sum

aggregate([{$group: {_id:null, cou: {$sum:1}}}])                #相當於select count(*) cou from dev
aggregate([{$group: {_id:null, totalAge: {$sum:"$age"}}}])      #相當於select sum(age) totalAge from dev
aggregate([{$group: {_id:"$name", totalAge: {$sum:"$age"}}}])   #相當於select name _id, sum(age) totalAge from dev group by name

條件篩選:$match

aggregate([{$match: {age: {$gt:20}}}, {$group: {_id:null, cou: {$sum:1}}}])                    #相當於select count(*) cou from dev where age>20
aggregate([{$group: {_id:"$name", totalAge: {$sum:"$age"}}}, {$match:{totalAge: {$gt:25}}}])   #相當於select name _id, sum(age) totalAge from dev group by name having totalAge>25

最大、最小、平均值:$max、$min、$avg

aggregate([{$group: {_id:null, maxAge: {$max:"$age"}}}])        #相當於select max(age) maxAge from dev
aggregate([{$group: {_id:null, minAge: {$min:"$age"}}}])        #相當於select min(age) minAge from dev
aggregate([{$group: {_id:null, avgAge: {$avg:"$age"}}}])        #相當於select avg(age) avgAge from dev

統計結果返回陣列:$push、$addToSet

aggregate([{$group: {_id:"$name", ageArr: {$push:"$age"}}}])        #按照name分組,使用陣列返回組內所有的age值(不會去重)
aggregate([{$group: {_id:"$name", ageArr: {$addToSet:"$age"}}}])    #按照name分組,使用陣列返回組內所有的age值(會去重)

陣列欄位拆分:$unwind

注意:文件中沒有tags欄位的不會顯示

aggregate([{$unwind:"$tags"}])   #將集合中所有tags欄位(陣列)拆分成單個顯示。比如某個文件中tags有三個元素,則會拆分成三條資料

聚合投影查詢 $project

注意:$project後面的投影查詢,欄位後面既可以使用變數(如"$name"),也可以使用數字(0或1)。不過,如果想欄位名稱取別名,則只能使用變數

aggregate([{$unwind:"$tags"}, {$project:{_id:0,name:"$name", tags:1}}])       #將tags陣列的內容拆分,並只顯示name和tags鍵

字串操作 $project

注意:$concat中的欄位變數只能為字串型別

aggregate([{$project:{_id:0, Name:{$toUpper:"$name"}}}])                                       #name的值轉為大寫並取別名Name。轉小寫:toLower
aggregate([{$unwind:"$tags"}, {$project:{_id:0, nameTags:{$concat:["$name", "-", "$tags"]}}}]) #將tags陣列的內容拆分,name欄位和tags欄位拼接並取別名nameTags
aggregate([{$project:{_id:0, namePrefix:{$substr:["$name", 0, 3]}}}])                          #只顯示name欄位前三個字元並取別名namePrefix

日期處理

MongoDB中的時間會比系統當前時間少8h。因為預設是UTC時區,而中國的時區是東八區,比UTC快8h

插入日期

insert({time:new Date()})                         #會比系統時間少8h
insert({time:new Date("2020-05-20T10:30:46Z")})   #必須嚴格按照日期格式,否則插入的日期或時間會有問題
insert({time:ISODate("2020-05-20 10:30:46")})     #ISODate為內建函式,不用完全按照上面的日期格式,它會自動轉成正確的

日期過濾查詢

find({time: {$eq:new Date("2020-05-20T10:30:46Z")}})  
find({time: {$gt:ISODate("2020-05-20 10:30:46")}})

日期處理查詢

注意:$dayOfWeek:星期日為1,星期六為7,$week:計數從0開始

aggregate([{$match:{time: {$ne:null}}},{$project:{year:{$year:"$time"}, month:{$month:"$time"}, day:{$dayOfMonth:"$time"}}}])   #查詢time欄位的年、月、日
aggregate([{$match:{time: {$ne:null}}},{$project:{hour:{$hour:"$time"}, minute:{$minute:"$time"}, second:{$second:"$time"}, milSec:{$millisecond:"$time"}}}])   #查詢time欄位的時、分、秒、毫秒
aggregate([{$match:{time: {$ne:null}}},{$project:{星期:{$dayOfWeek:"$time"}, 全年第幾周:{$week:"$time"}, 全年第幾天:{$dayOfYear:"$time"}}}])

顯示自定義日期格式

aggregate([{$match:{time: {$ne:null}}},{$project:{myTime:{$dateToString:{format:"%Y-%m-%d %H:%M%S", date:"$time"}}}}])

更新

語法格式:update({查詢條件}, {更新內容}, {更新引數(可選)})

update({name:"zhangsan"},{age:100})                          #文件更新成指定的內容,即更新後文檔只有_id和age欄位了
update({name:"zhangsan"},{$set: {age:200}})                  #加了$set,只更新指定欄位,不會改變文件欄位(只會更新第一條資料)
update({name:"zhangsan"},{$set: {age:200}, {multi:true}})    #multi表示會更新所有資料

索引

建立索引

語法格式:createIndex({建立索引的鍵: 排序規則}, {建立索引引數(可選)})

createIndex({name:1})       #為name建立正序索引
createIndex({name:1, age:-1},{name:"idx_name_age"})    #為name和age建立複合索引,索引名稱為idx_name_age

排序規則:1:正序 -1倒序

索引引數:

引數 資料型別 預設值 功能
background Boolean false 後臺建立索引,建立索引時不阻塞其它操作
expireAfterSeconds Integer 指定索引過期時間
name String 指定索引名稱,如果未指定,MongoDB會生成一個索引欄位名稱_排序順序的名稱
sparse Boolean false 對文件中不存在的欄位資料不啟用索引
unique Boolean false 建立唯一索引

注意點:如果集合中欄位索引已存在,再次為該欄位建立索引不會生效

檢視索引

getIndexes()              #檢視集合中所有索引資訊
getIndexKeys()            #檢視集合中所有的索引鍵
totalIndexSize(可選引數)   #檢視集合中索引的大小,單位位元組。引數說明:可選引數為0、false或者空,顯示所有索引的總大小,其它值顯示每個索引的大小及總大小

刪除索引

dropIndex("idx_name")    #刪除索引名稱為idx_name的索引
dropIndexes()            #刪除全部索引,_id鍵的索引除外

重建索引

使用場景:資料大量變化後,可以使用重建索引構建更高效的B-Tree,優化索引查詢效率

過程說明:重建索引是刪除原索引重新建立的過程,不建議反覆使用

reIndex()