一、查詢文件
1、查詢所有
MongoDB 查詢資料的語法格式如下:
db.uesr.find() # 等同於 db.user.find({})
# 根據 name 去重
db.user.distinct("name")
find() 方法以非結構化方式來顯示所有文件。
如果你需要以易讀的方式來讀取資料,可以使用 pretry() 方法,語法格式如下:
db.user.find().pretty()
pretty() 函式以格式化的方式來顯示所有文件
注:在MongoDB中,用到方法都得用 $ 符號開頭
2、比較運算子
=、!= ('$ne')、> ('$gt')、< ('$lt')、>= ('$gte')、<= ('$lte')
# 1、select * from user where id = 3
db.user.find({"id":3})
# 2、select * from user where id != 3
db.user.find({"_id":{"$ne":3}})
# 3、select * from user where id > 3
db.user.find({"_id":{"$gt":3}})
# 4、select * from user where id < 3
db.user.find({"_id":{"$lt":3}})
# 5、select * from user where id >= 3
db.user.find({"_id":{"$gte":3}})
# 6、select * from user where id <= 3
db.user.find({"_id":{"$lte":3}})
3、邏輯運算
MongoDB 中字典內用逗號分隔多個條件是 and 關係,或者直接用 $and
,$or
,$not
(與或非)
# 邏輯運算:$and,$or,$ont
# 1、select * from user where id >= and id <= 4;
db.user.find({"id":{"$gte":3,"$lte":4}})
# 2、select * from user where id >= 3 and id <= 4 and age >= 4;
db.user.find({
"_id":{"$gte":3,"$lte":4},
"age":{"$gte":4}
})
db.user.find({
"$and":[
{"_id":{"$gte":3,"$lte":4}},
{"age":{"$gte":4}}
]
})
# 3、select * from user where id >=0 and id <= 1 or id >=4 or name = "test"
db.user.find({
"$or":[
{"_id":{"$gte":0,"$lte":1}},
{"_id":{"$lte":4}},
{"name":"test"}
]
})
# 4、select * from user where id % 2 = 1;
db.user.find({"_id":{"$mod":[2,1]}})
# 5、select * from user where id % 2 != 1;
db.user.find({"_id":{"$not":{"$mod":[2,1]}}})
4、$type 操作符
MongoDB 中可以使用的型別如下表所示:
# 查詢 name 是字串型別的資料
db.user.find({name:{$type:2}}).pretty()
5、正則
# 1、select * from user where name regexp '^z.*?(u|i)$'
# 匹配規則:z開頭、n或u結尾,不區分大小寫
db.user.find({name:/^z.*?(u|n)/i})
6、投影
MongoDB 投影意思是隻選擇必要的資料而不是選擇一整個檔案的資料。
在 MongoDB 中,當執行 find()方法,那麼它會顯示一個文件所有欄位。要限制這一點需要設定欄位列表值 1 或 0
1 用來顯示欄位而 0 用來隱藏欄位,_id 會預設顯示出來。
# 1、select name,age from user where id = 3;
db.user.find({'_id':3},{'_id':0,'name':1,'age':1})
# 2、select name,age from user where name regexp "^z.*(n|u)$";
db.user.find({
"name":/^z.*(n|u)$/i
},
{
"_id":0,
"name":1,
"age":1
}
)
7、陣列
# 查詢陣列相關
# 查詢 hobbies 中有 dancing 的人
db.user.find({
"hobbies":"dancing"
})
# 檢視既有 dancing 愛好又有 tea 愛好的人
db.user.find({
"hobbies":{"all":["dancing","tea"]}
})
# 檢視索引第二個愛好為 dancing 的人(索引從 0 開始計算)
db.user.find({
"hobbies.1":"dancing"
})
# 檢視所有人的第1個到第3個愛好,第一個{}表示查詢條件為所有,第二個是顯示條件(左閉右開)
db.user.find(
{},
{
_id:0,
name:0,
age:0
addr:0
hobbies:{"$slice":[0,2]}
}
)
# 檢視所有人的最後兩個愛好,第一個{}表示查詢條件為所有,第二個是顯示條件(左閉右開)
db.user.find(
{},
{
_id:0,
name:0,
age:0
addr:0
hobbies:{"$slice":-2}
}
)
# 查詢子文件有 "country":"China"的人
db.user.find(
{
"addr.country":"China"
}
)
8、排序
在 MongoDB 中使用 sort() 方法來對資料排序, sort() 方法可以通過引數指定排序的欄位,並使用 1 和 -1 來指定排序的方式,其中 1 為升序排序,而 -1 是用於降序排序
# 按照姓名正序
db.user.find().sort({name:1})
# 按照年齡到序序,id正序
db.user.find().sort({age:-1,_id:1})
9、分頁
limit 表示取多少個 document,skip代表跳過幾個document
分頁公式:db.user.find().skip((pageNumber-1)*pageSize).limit(pageSize)
db.user.find().limit(2).skip(0) # 前兩個
db.user.find().limit(2).skip(2) # 第三個和第四個
db.user.find().limit(3).skip(4) # 第五個和第六個
10、統計
# 查詢 _id 大於 3 的人數
# 方式一
db.user.count({_id:{"$gt":3}})
# 方式二
db.user.find({_id:{"$gt":3}}).count()
二、聚合
我們在查詢時可定會用到聚合,在 MongoDB 中聚合為 aggregate,集合函式主要用到 $match $group $avg $project $concat,可以加"$match"也可以不加$match
2.1、Aggregate與法
基本格式:db.COLLECTION_NAME.aggregate(pipeline,options)
引數說明
引數 | 型別 | 描述 |
---|---|---|
pipeline | array | 一系列資料聚合擦耦走或階段。在版本 2.6 中更改:該方法仍然可以將流水線階段作為單獨的引數接受,而不是作為陣列中的元素;但是,如果不將管道指定為陣列,則不能指定 options 引數。目前所使用的 4.0.4 版本必須使用陣列 |
options | document | 可選。aggreate() 傳遞給聚合命令的其它選項,2.6 版本中新增功能:僅當將管道指定為陣列時才可用 |
2.6 中的新增功能,僅當將管道指定為陣列時才可用。
注意:使用 db.collection.aggregate() 直接查詢會提示錯誤,但是傳入一個空陣列如 db.collection.aggregate([]) 則不會報錯,且會和 find 一樣返回所有文件。
2.2、$match 和 $group
相當於 sql 語句中的 where 和 group by
{"$match":{"欄位":"條件"}},可以使用任何常用的查詢操作符 $gt,$lt,$in等
{"$group":{"_id":分組欄位,"新的欄位名":聚合操作符}}
# select * from db1.emp where post = "公務員"
db.emp.aggregate([{"$match":{"post":"公務員"}}])
# select * from db1.emp where id > 3 group by post;
db.emp.aggregate([
{"$match":{_id:{"$gt":3}}},
{"$group":{_id:"$post","avg_salary":{"$avg":"$salary"}}}
])
# select * from db1.emp where id > 3 group by post having avg(salary) > 10000;
db.emp.aggregate([
{"$match":{_id:{"$gt":3}}},
{"$group":{_id:"$post","avg_salary":{"$avg":"$salary"}}},
{"$match":{"avg_salary":{"$gt":10000}}}
])
{"$group":{_id:分組欄位,"新的欄位":聚合操作符}}
將分組欄位傳給 $group 函式的 _id 欄位即可
{"$group":{_id:"$sex"}} # 按照性別分組
{"$group":{_id:"$post"}} # 按照職位分組
{"$group":{_id:{"state":"$state","city":"$city"}}} # 按照多個欄位分組,比如按照州市分組
# 分組後聚合得結果,類似於 sql 中聚合函式的聚合操作符:$sum,$avg,$max,$min,$first,$last
# select post,max(salary) from db1.emp group by post;
db.emp.aggregate([{"$group":{_id:"$post","max_salary":{"$max":"$salary"}}}])
# 取每個部門最大薪資與最低薪資
db.emp.aggregate(["$group":{_id:"$post","max_salary":{"$max":"$salary"},"min_salary":{"$min":"$salary"}}])
# 如果欄位是排序後的,那麼 $first,$last 會很有用,比如$max 和 $min 效率高
db.emp.aggregate(["$group":{_id:"$post","first_id":{"$first":"$_id"}}}])
# 求每個部門的工資
db.emp.aggregate([{"$group":{_id:"$post","count":{"$sum":"$salary"}}},{"$sort":{"count":1}}])
# 求每個部門人數
db.emp.aggregate([{"$group":{_id:"$post","count":{"$sum":1}}},{"$sort":{"count":1}}])
# 陣列操作符
{"$addToSet":expr} # 不重複
{"$push":expr} # 重複
# 查詢崗位名以及各崗位的員工姓名:select post,group_concat(name) from db.emp group by post;
# 重複的也查詢出來
db.emp.aggregate([{"$group":{_id:"$post","names":{"$push":"$name"}}}])
# 查詢不重複的,如果有重複的保留一個
db.emp.aggregate([{"$group":{_id:"$post","names":{"$addToSet":"$name"}}}])
2.3、$project
用於投射,即設定該該鍵值對是否保留,1為保留,0位不保留,可對原有鍵值對做操作後增加自定義表示式(查詢哪些要顯示的列)
{"$project":{"要保留的欄位名":1,"要去掉的欄位名":"0","新增欄位名":" 表示式"}}
# select name,post,(age+1) as new_age from db1.emp;
db.emp.aggregate([
{
$project:{
"name":1,
"post:"1,
"new_age":{"$add":["$age",1]}
}
}
])
2.4、$sort 和 $limit 和 $skip
排序:{"$sort":{"欄位名稱":1,"欄位名":-1}} #1 升序,-1 降序
限制:{"$limit":n}
跳過:{"$skip":n} # 跳過多少個文件
# 取平均工資最高的前兩個部門
db.emp.aggregate([
{
"$group":{_id:"$post","平均工資":{"$age":"$salary"}}
},
{
"$sort":{"平均工資":-1}
},
{
"$limit":2
}
])
# 取平均工資最高的第二個部門
db.emp.aggregate([
{
"$group":{_id:"$post","平均工資":{"$avg":"$salary"}}
},
{
"$sort":{"平均工資":-1}
},
{
"$limit":2
},
{
"$skip":1
}
])
2.5、$sample
隨機取幾個:$sample
# 隨機獲取 3 個文件
db.emp.aggregate([
{$sample:{size:3}}
])
2.6、$concat 和 $substr 和 $toLower 和 $toUpper
{"$substr":[$值為字串的欄位名,起始位置,擷取幾個位元組]}
# 指定的表示式或字串連線在一起返回,只支援字串拼接
{"$concat":[expr1,expr2,...,exprN]}
{"$toLower":expr} # 轉小寫
{"$toUpper":expr} # 轉大寫
# 擷取字串
db.emp.aggregate([
{
$project:{
_id:0
"str":{$substr:["$sex",0,2]}
}
}
])
# 拼接
db.emp.aggregate([
{
$project:{
"name":1
"post":1,
"name_sex":{$concat:["$name","測試","$sex"]}
}
}
])
# 將性別的英文轉為大寫
db.emp.aggreagate([$project:{"sex":{"$toUpper":"$sex"}}])
本作品採用《CC 協議》,轉載必須註明作者和本文連結