一、mongodb的查询语句
db.getCollection('bizData').find(query, projection)
1、query :可选,使用查询操作符指定查询条件
2、projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。
示例:db.getCollection('orderItem').find({"status":"done"},{"name":1})
查找status为done的记录,并且只返回name字段
$gt ,$gte,$lt,$lte,$ne ,$eq ,$in,$and,$or,$regex
示例:
db.col.find({"likes": {$gt:50}, $or: [{"by": "菜鸟教程"},{"title": "MongoDB 教程"}]}).pretty()
二、聚合操作
示例1:根据status状态分组,得到不同状态下的多个记录的tPrice的平均值
db.getCollection('orderItem').aggregate( [
{ $group: { _id: "$status", count: { $avg: "$tPrice"} } } ] );
结果:
{
"_id" : "error",
"count" : 0.0
}
{
"_id" : "done",
"count" : 0.888539114043355
}
示例2:得到不同状态下的记录数
db.getCollection('orderItem').aggregate( [
{ $group: { _id: "$status", count: { $sum: 1} } } ] );
结果:
{
"_id" : "error",
"count" : 794.0
}
{
"_id" : "done",
"count" : 1754.0
}
1、$sum 计算总和。
db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}])
如果要指定分组中记录的某个字段的求和,就要使用 $字段,如果只是统计分组的数量,使用1即可。
2、$avg 计算平均值
db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}])
3、$min 获取集合中分组后每个组所有文档对应值得最小值。
db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}])
4、$max 获取集合中分组后每个组所有文档对应值得最大值。
db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}])
5、$push 在结果文档中插入值到一个数组中。
db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}])
6、$addToSet 在结果文档中插入值到一个数组中,但不创建副本。
db.mycol.aggregate([{$status: {_id : "$group", count: {$addToSet : "$customer"}}}])
{
"_id" : "error",
"count" : [
"关圣融资租赁(上海)有限公司",
"中融信(天津)融资租赁有限公司"
]
}
{
"_id" : "done",
"count" : [
"关圣融资租赁(上海)有限公司",
"中融信(天津)融资租赁有限公司"
]
}
7、$first 根据资源文档的排序获取第一个文档数据。
db.mycol.aggregate([{$group : {_id : "$status", count: {$first : "$_id"}}}])
{
"_id" : "error",
"count" : ObjectId("5b4410dda3cffb00014a6c15")
}
{
"_id" : "done",
"count" : ObjectId("5b3f1e7fa3cffb00014a6bc8")
}
8、$last 根据资源文档的排序获取最后一个文档数据
db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}])
三、管道操作
MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。
db.collection.aggregate( [ {
1、$project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
db.getCollection('orderItem').aggregate( [
{ $project : { _id : 0 ,name : 1 , status : 1 ,}} ] );
只输出name和status两个字段,id默认显示,所以需要手动id为0
2、$match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
db.articles.aggregate( [
{ $match : { score : { $gt : 70, $lte : 90 } } },
{ $group: { _id: null, count: { $sum: 1 } } } ] );
$match用于获取分数大于70小于或等于90记录,然后将符合条件的记录送到下一阶段$group管道操作符进行处理,根据null分组,实际上统计分数大于70小于或等于90的记录。
3、$limit:用来限制MongoDB聚合管道返回的文档数。
4、$skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
db.article.aggregate(
{ $skip : 5 });
经过$skip管道操作符处理后,前五个文档被"过滤"掉。
5、$unwind:将文档中的一条记录的某一个数组类型字段拆分成多条记录,每条包含数组中的一个值。其他不变
6、$group:将集合中的文档分组,可用于统计结果。
7、$sort:将输入文档排序后输出。
8、$geoNear:输出接近某一地理位置的有序文档。
9、$sample:从待操作的集合中随机返回指定数量的文档 注意:如果指定的数量 N 大于等于集合文档总数的5%,$sample 执行集合扫描,执行排序,然后选择前 N 的文档(受排序的内存限制) 如果 N 是小于 5%的集合中的文档总数 如果使用 WiredTiger 存储引擎,$sample 使用伪随机游标在抽样 N 文档集合。 如果使用 MMAPv1 存储引擎,$sample 使用 _id 索引随机选择 N 个文档。
10、$lookup:用于与统一数据库中其他集合之间进行join操作
11、$out:用户将聚合的结果输出到指定的集合,如果要使用$out则必须在整个管道操作的最后阶段 如果指定的集合尚不存在,$out 操作会在当前数据库中创建一个新的集合。集合不是可见的直到聚合完成。如果聚合失败,MongoDB 不会创建集合。 如果集合指定的 $out 操作已经存在,然后完成后的聚合,$out 阶段以原子方式以新的结果集合替换现有集合的,$out 操作不会更改任何存在于以前的集合的索引。如果聚合失败$out 则不会对现有集合做任何更改。
12、 $addFields:增加字段
{ $addFields: {
示例:增加两个字段,为字段homework数组的和
{
_id: 1,
student: "Maya",
homework: [ 10, 5, 10 ],
quiz: [ 10, 8 ],
extraCredit: 0
}
db.scores.aggregate( [
{
$addFields: {
totalHomework: { $sum: "$homework" } ,
totalQuiz: { $sum: "$quiz" }
}
}
])
第二种格式:
db.runCommand({
aggregate: "",
pipeline: [ , <...> ],
explain: ,
allowDiskUse: ,
cursor: ,
bypassDocumentValidation:
})
//或
db.collection.aggregate([ , <...> ], options)
参数说明:
aggregate:要聚合的集合名称
pipeline:管道操作符
explain:返回指定aggregate各个阶段管道的执行计划信息
allowDiskUse:每个阶段管道限制为100MB的内存,如果大于100MB的数据可以先写入临时文件。设置为true时,aggregate操作可时可以先将数据写入对应数据目录的子目录中 的唯一并以_tmp结尾的文档中。
cursor:指定游标的初始批批大小。光标的字段的值是一个与场batchSize文件。
bypassDocumentValidation:只有当你指定了$out操作符,使db.collection.aggregate:绕过文档验证操作过程中。这让您插入不符合验证要求的文档。
示例1:
db.runCommand({
'aggregate': 'bizData',
'pipeline': [{
'$match': {
$and: [{
'state': {
'$in': ["FIN_EXAMING",
"FIN_RETURN",
"CAR_PASS"]
}
},
{
$or: [{
name: {
'$regex': '李',
'$options': 'i'//不区分大小写
}
},
{
idNum: {
'$regex': '李',
'$options': 'i'
}
},
{
phone: {
'$regex': '李',
'$options': 'i'
}
}]
}]
}
},
{
'$addFields': {//增加字段sortFlag,记录的state在集合中的索引是0返回0,不存在-1
'sortFlag': {
'$indexOfArray': [["FIN_EXAMING"],
'$state']
}
}
},
{
'$addFields': {//增加sortFlag,记录的sortFlag是否等于-1,是返回100,否sortFlag,也就是0
'sortFlag': {
'$cond': [{
'$eq': ['$sortFlag',
-1]
},
100,
'$sortFlag']
}
}
},
{
'$sort': {
'sortFlag': 1,//按sortFlag正序排序
'modifiedDate': -1//按modifiedDat逆序排序
}
},
{
'$skip': 0
},
{
'$limit': 10
}],
'cursor': {
},
'allowDiskUse': true
})
示例2:
db.getCollection('bizData').aggregate([{
'$match': {
$and: [{
'state': {
'$in': ["FIN_EXAMING",
"FIN_RETURN",
"CAR_PASS"]
}
},
{
$or: [{
name: {
'$regex': '李',
'$options': 'i'
}
},
{
idNum: {
'$regex': '李',
'$options': 'i'
}
},
{
phone: {
'$regex': '李',
'$options': 'i'
}
}]
}]
}
},
{
'$addFields': {
'sortFlag': {
'$indexOfArray': [["FIN_EXAMING"],
'$state']
}
}
},
{
'$addFields': {
'sortFlag': {
'$cond': [{
'$eq': ['$sortFlag',
-1]
},
100,
'$sortFlag']
}
}
},
{
'$sort': {
'sortFlag': 1,
'modifiedDate': -1
}
},
{
'$skip': 0
},
{
'$limit': 10
}],
{
'allowDiskUse': true,
'cursor': {
}
});
四、数学表达式
1、{ $add: [
db.getCollection('bizData').aggregate([{
$project: {
"orderid": '$_id',//重命名字段_id
"version_copy": "$version",//重命名字段version
"state_copy": "$state",//重命名字段state
"add": {
"$add": ["$version",
1]
}
}
}])
结果:
{
"_id" : ObjectId("5944f908d100680001be175e"),
"orderid" : ObjectId("5944f908d100680001be175e"),
"version_copy" : NumberLong(1),
"state_copy" : "BIGDATA_RETURN",
"add" : 2.0
}
由于重命名之后的字段没有索引,如果要排序的话,先排序,再做字段重命名。
2、{ $subtract: [
db.order.aggregate({
$project: {
"subtract": {
"$subtract": [{ "$add": ["$price", 12] }, 10]
}
}
})
3、{ $multiply: [
db.order.aggregate({
$project: {
"multiply": { "$multiply": ["$price", 3] }
}
})
4、{ $divide: [
db.order.aggregate({
$project: {
"divide": { "$divide": ["$price", 3] }
}
})
5、{ $cond: { if:
db.order.aggregate({
$project: {
"price": {
"$cond": { if: { $gt: ["$price", 25] }, then: true, else: false }
}
}
});
//或
db.order.aggregate({
$project: {
"price": {
"$cond": [{ $gt: ["$price", 25] }, true, false]
}
}
})
6、{$ifNull: [
db.order.aggregate({
$project: {
"total": {
"$ifNull": ["$total", 0]//total字段为null返回0,不是返回total
}
}
})
7、{ $and: [
//Example Result
{ $and: [1, “green”] } true
{ $and: [] } true
{ $and: [[null], [false], [0]] } true
{ $and: [null, true] } false
{ $and: [0, true] } false
8、{ $or: [
9、{ $not: [
10、$match 过滤操作,筛选符合条件文档,作为下一阶段的输入 $match的语法和查询表达式db.collection.find() 的语法相同
11、$out 用户将聚合的结果输出到指定的集合
db.order.aggregate([{
$match: {
cust_id: "1"
}
},
{
$project: {
"total": {
"$ifNull": ["$total",
0]
}
}
},
{
$out: "testaggregate"
}])