1. 条件操作符
条件操作符用于比较两个表达式并从MongoDB集合中获取数据。
MongoDB中条件操作符有:
(>) 大于 - $gt
(<) 小于 - $lt
(>=) 大于等于 - $gte
(<= ) 小于等于 - $lte
清空集合数据
db.col.remove({})
插入以下数据
> db.col.insert({
title: '测试数据200',
description: '关注公众号,小罗技术笔记,专注于开发技术的研究与知识分享',
by: '小罗技术笔记',
url: 'http://www.yuwowugua.com',
tags: ['test'],
likes: 200
})
> db.col.insert({
title: '测试数据150',
description: '关注公众号,小罗技术笔记,专注于开发技术的研究与知识分享',
by: '小罗技术笔记',
url: 'http://www.yuwowugua.com',
tags: ['test'],
likes: 150
})
> db.col.insert({
title: '测试数据100',
description: '关注公众号,小罗技术笔记,专注于开发技术的研究与知识分享',
by: '小罗技术笔记',
url: 'http://www.yuwowugua.com',
tags: ['test'],
likes: 100
})
使用find()命令查看数据:
> db.col.find()
{ "_id" : ObjectId("5a6a083598891b4abe9cc8cc"), "title" : "测试数据200", "description" : "关注公众号,小罗技术笔记,专注于开发技术的研究与知识分享", "by" : "小罗技术笔记", "url" : "http://www.yuwowugua.com", "tags" : [ "test" ], "likes" : 200 }
{ "_id" : ObjectId("5a6a083e98891b4abe9cc8cd"), "title" : "测试数据150", "description" : "关注公众号,小罗技术笔记,专注于开发技术的研究与知识分享", "by" : "小罗技术笔记", "url" : "http://www.yuwowugua.com", "tags" : [ "test" ], "likes" : 150 }
{ "_id" : ObjectId("5a6a084498891b4abe9cc8ce"), "title" : "测试数据100", "description" : "关注公众号,小罗技术笔记,专注于开发技术的研究与知识分享", "by" : "小罗技术笔记", "url" : "http://www.yuwowugua.com", "tags" : [ "test" ], "likes" : 100 }
1.1 (>) 大于操作符 - $gt
db.col.find({"likes" : {$gt : 100}})
类似于SQL语句:
select * from col where likes > 100;
输出结果
{ "_id" : ObjectId("5a6a083598891b4abe9cc8cc"), "title" : "测试数据200", "description" : "关注公众号,小罗技术笔记,专注于开发技术的研究与知识分享", "by" : "小罗技术笔记", "url" : "http://www.yuwowugua.com", "tags" : [ "test" ], "likes" : 200 }
{ "_id" : ObjectId("5a6a083e98891b4abe9cc8cd"), "title" : "测试数据150", "description" : "关注公众号,小罗技术笔记,专注于开发技术的研究与知识分享", "by" : "小罗技术笔记", "url" : "http://www.yuwowugua.com", "tags" : [ "test" ], "likes" : 150 }
1.2 (>=)大于等于操作符 - $gte
如果你想获取”col”集合中 “likes” 大于等于 100 的数据,你可以使用以下命令:
db.col.find({likes : {$gte : 100}})
类似于SQL语句:
select * from col where likes >=100;
输出结果:
{ "_id" : ObjectId("5a6a083598891b4abe9cc8cc"), "title" : "测试数据200", "description" : "关注公众号,小罗技术笔记,专注于开发技术的研究与知识分享", "by" : "小罗技术笔记", "url" : "http://www.yuwowugua.com", "tags" : [ "test" ], "likes" : 200 }
{ "_id" : ObjectId("5a6a083e98891b4abe9cc8cd"), "title" : "测试数据150", "description" : "关注公众号,小罗技术笔记,专注于开发技术的研究与知识分享", "by" : "小罗技术笔记", "url" : "http://www.yuwowugua.com", "tags" : [ "test" ], "likes" : 150 }
{ "_id" : ObjectId("5a6a084498891b4abe9cc8ce"), "title" : "测试数据100", "description" : "关注公众号,小罗技术笔记,专注于开发技术的研究与知识分享", "by" : "小罗技术笔记", "url" : "http://www.yuwowugua.com", "tags" : [ "test" ], "likes" : 100 }
1.3 (<) 小于操作符 - $lt
如果你想获取”col”集合中 “likes” 小于 150 的数据,你可以使用以下命令:
db.col.find({likes : {$lt : 150}})
类似于SQL语句:
select * from col where likes < 150;
输出结果:
> db.col.find({likes : {$lt : 150}})
{ "_id" : ObjectId("5a6a084498891b4abe9cc8ce"), "title" : "测试数据100", "description" : "关注公众号,小罗技术笔记,专注于开发技术的研究与知识分享", "by" : "小罗技术笔记", "url" : "http://www.yuwowugua.com", "tags" : [ "test" ], "likes" : 100 }
1.4 (<=) 小于操作符 - $lte
如果你想获取”col”集合中 “likes” 小于等于 150 的数据,你可以使用以下命令
db.col.find({likes : {$lte : 150}})
类似于SQL语句:
select * from col where likes <= 150;
输出结果:
> db.col.find({likes : {$lte : 150}})
{ "_id" : ObjectId("5a6a083e98891b4abe9cc8cd"), "title" : "测试数据150", "description" : "关注公众号,小罗技术笔记,专注于开发技术的研究与知识分享", "by" : "小罗技术笔记", "url" : "http://www.yuwowugua.com", "tags" : [ "test" ], "likes" : 150 }
{ "_id" : ObjectId("5a6a084498891b4abe9cc8ce"), "title" : "测试数据100", "description" : "关注公众号,小罗技术笔记,专注于开发技术的研究与知识分享", "by" : "小罗技术笔记", "url" : "http://www.yuwowugua.com", "tags" : [ "test" ], "likes" : 100 }
1.5 使用 (<) 和 (>) 查询 - lt和gt
如果你想获取”col”集合中 “likes” 大于100,小于 200 的数据,你可以使用以下命令:
db.col.find({likes : {$lt :200, $gt : 100}})
类似于SQL语句:
select * from col where likes>100 AND likes<200;
输出结果:
> db.col.find({likes : {$lt :200, $gt : 100}})
{ "_id" : ObjectId("5a6a083e98891b4abe9cc8cd"), "title" : "测试数据150", "description" : "关注公众号,小罗技术笔记,专注于开发技术的研究与知识分享", "by" : "小罗技术笔记", "url" : "http://www.yuwowugua.com", "tags" : [ "test" ], "likes" : 150 }
一些简写说明:
$gt -------- greater than >
$gte --------- gt equal >=
$lt -------- less than <
$lte --------- lt equal <=
$ne ----------- not equal !=
$eq -------- equal =
2、 Limit与Skip方法
MongoDB Limit() 方法
如果你需要在MongoDB中读取指定数量的数据记录,可以使用MongoDB的Limit方法,limit()方法接受一个数字参数,该参数指定从MongoDB中读取的记录条数。
插入测试数据
db.col.insert({title: 'MongoDB-1'})
db.col.insert({title: 'MongoDB-2'})
db.col.insert({title: 'MongoDB-3'})
db.col.insert({title: 'MongoDB-4'})
MongoDB Enterprise > db.col.find()
{ "_id" : ObjectId("5a6e8eaef14a3f270ba2dd0c"), "title" : "MongoDB-1" }
{ "_id" : ObjectId("5a6e8ec8f14a3f270ba2dd0d"), "title" : "MongoDB-2" }
{ "_id" : ObjectId("5a6e8ecbf14a3f270ba2dd0e"), "title" : "MongoDB-3" }
{ "_id" : ObjectId("5a6e8ed5f14a3f270ba2dd0f"), "title" : "MongoDB-4" }
MongoDB Enterprise >
limit()方法基本语法如下所示:
> db.COLLECTION_NAME.find().limit(NUMBER)
以上实例为显示查询文档中的两条记录:
MongoDB Enterprise > db.col.find().limit(2)
{ "_id" : ObjectId("5a6e8eaef14a3f270ba2dd0c"), "title" : "MongoDB-1" }
{ "_id" : ObjectId("5a6e8ec8f14a3f270ba2dd0d"), "title" : "MongoDB-2" }
MongoDB Enterprise > db.col.find({},{"title":1,_id:0}).limit(2)
{ "title" : "MongoDB-1" }
{ "title" : "MongoDB-2" }
MongoDB Enterprise >
注:如果你们没有指定limit()方法中的参数则显示集合中的所有数据。
MongoDB Enterprise > db.col.find({},{"title":1,_id:0}).limit()
{ "title" : "MongoDB-1" }
{ "title" : "MongoDB-2" }
{ "title" : "MongoDB-3" }
{ "title" : "MongoDB-4" }
Skip() 方法
我们除了可以使用limit()方法来读取指定数量的数据外,还可以使用skip()方法来跳过指定数量的数据,skip方法同样接受一个数字参数作为跳过的记录条数。
skip() 方法脚本语法格式如下:
> db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
实例
以上实例只会显示第二条文档数据
MongoDB Enterprise > db.col.find({},{"title":1,_id:0}).limit(1).skip(1)
{ "title" : "MongoDB-2" }
MongoDB Enterprise >
注:skip()方法默认参数为 0
3、排序
在MongoDB中使用使用sort()方法对数据进行排序,sort()方法可以通过参数指定排序的字段
使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而-1是用于降序排列。
sort()方法基本语法如下所示:
> db.COLLECTION_NAME.find().sort({KEY:1})
col 集合中的数据如下:
MongoDB Enterprise > db.col.find()
{ "_id" : ObjectId("5a6e8eaef14a3f270ba2dd0c"), "title" : "MongoDB-1" }
{ "_id" : ObjectId("5a6e8ec8f14a3f270ba2dd0d"), "title" : "MongoDB-2" }
{ "_id" : ObjectId("5a6e8ecbf14a3f270ba2dd0e"), "title" : "MongoDB-3" }
{ "_id" : ObjectId("5a6e8ed5f14a3f270ba2dd0f"), "title" : "MongoDB-4" }
MongoDB Enterprise >
其中 1 为升序排列,而-1是用于降序排列
以下实例演示了 col 集合中的数据按字段 title 的降序排列:
MongoDB Enterprise > db.col.find({},{"title":1,_id:0}).sort({"title":-1})
{ "title" : "MongoDB-4" }
{ "title" : "MongoDB-3" }
{ "title" : "MongoDB-2" }
{ "title" : "MongoDB-1" }
MongoDB Enterprise >
注: 如果没有指定sort()方法的排序方式,默认按照文档的升序排列。
4、索引
索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。
这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。
索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构
MongoDB使用 ensureIndex() 方法来创建索引。ensureIndex()方法基本语法格式如下所示:
> db.COLLECTION_NAME.ensureIndex({KEY:1})
语法中 Key 值为你要创建的索引字段,1为指定按升序创建索引,如果你想按降序来创建索引指定为-1即可。
> db.COLLECTION_NAME.ensureIndex({KEY:1})
语法中 Key 值为你要创建的索引字段,1为指定按升序创建索引,如果你想按降序来创建索引指定为-1即可。
MongoDB Enterprise > db.col.ensureIndex({"title":1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
MongoDB Enterprise >
db.col.insert({title: 'MongoDB 教程',
description: 'MongoDB 是一个 Nosql 数据库',
by: '搜云库教程-专注于开发技术的研究与知识分享',
url: 'http://www.souyunku.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
})
ensureIndex() 方法中你也可以设置使用多个字段创建索引(关系型数据库中称作复合索引)。
MongoDB Enterprise > db.col.ensureIndex({"title":1,"description":1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 3,
"numIndexesAfter" : 4,
"ok" : 1
}
ensureIndex() 接收可选参数,可选参数列表如下:
在后台创建索引:
建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 “background” 可选参数。 “background” 默认值为false。
MongoDB Enterprise > db.col.ensureIndex({"url":1}, {background: true})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 5,
"numIndexesAfter" : 6,
"ok" : 1
}
MongoDB Enterprise >
4、 聚合
MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。有点类似sql语句中的 count(*)。
aggregate() 方法
删除之前的测试数据
MongoDB Enterprise > db.col.remove({})
WriteResult({ "nRemoved" : 5 })
MongoDB Enterprise >
插入新的测试数据
db.col.insert({
title: 'MongoDB 教程',
description: 'MongoDB 是一个 Nosql 数据库',
by_user: '小罗',
url: 'http://www.yuwowugua.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
})
db.col.insert({
title: 'MongoDB 教程',
description: 'MongoDB 是一个 Nosql 数据库',
by_user: '小罗',
url: 'http://www.yuwowugua.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 200
})
db.col.insert({
title: 'MongoDB 教程',
description: 'MongoDB 是一个 Nosql 数据库',
by_user: '小罗',
url: 'http://www.yuwowugua.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 300
})
MongoDB Enterprise > db.col.find()
{ "_id" : ObjectId("5a6ebfab5326a260464a4072"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by_user" : "小罗", "url" : "http://www.yuwowugua.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }
{ "_id" : ObjectId("5a6ebfab5326a260464a4073"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by_user" : "小罗", "url" : "http://www.yuwowugua.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 200 }
{ "_id" : ObjectId("5a6ebfab5326a260464a4074"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by_user" : "小罗", "url" : "http://www.yuwowugua.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 300 }
MongoDB Enterprise >
MongoDB中聚合的方法使用aggregate(),基本语法格式如下所示:
> db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
MongoDB Enterprise > db.col.aggregate([{$group : {_id : "$by_user", num_tutorials : {$sum : 1}}}])
{
"_id": "小罗",
"num_tutorials": 3
}
MongoDB Enterprise > db.col.aggregate([{$group : {_id : "$by_user", totle : {$sum : 1}}}])
{
"_id": "小罗",
"totle": 3
}
MongoDB Enterprise >
以上实例类似sql语句:
select by_user, count(*) from col group by by_user
在上面的例子中,我们通过字段by_user字段对数据进行分组,并计算by_user字段相同值的总和。
管道的概念
管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数。
MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。
表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。
这里我们介绍一下聚合框架中常用的几个操作:
$project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
match:用于过滤数据,只输出符合条件的文档。
match使用MongoDB的标准查询操作。
$limit:用来限制MongoDB聚合管道返回的文档数。
$skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
$unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
$group:将集合中的文档分组,可用于统计结果。
$sort:将输入文档排序后输出。
$geoNear:输出接近某一地理位置的有序文档。
管道操作符实例
1、$project实例
MongoDB Enterprise > db.col.aggregate(
{ $project : {
title : 1 ,
by_user : 1 ,
}}
);
{ "_id" : ObjectId("5a6ebfab5326a260464a4072"), "title" : "MongoDB 教程", "by_user" : "小罗" }
{ "_id" : ObjectId("5a6ebfab5326a260464a4073"), "title" : "MongoDB 教程", "by_user" : "小罗" }
{ "_id" : ObjectId("5a6ebfab5326a260464a4074"), "title" : "MongoDB 教程", "by_user" : "小罗" }
MongoDB Enterprise >
这样的话结果中就只还有_id,tilte和by_user三个字段了,默认情况下_id字段是被包含的,如果要想不包含_id话可以这样:
MongoDB Enterprise > db.col.aggregate(
{ $project : {
_id : 0 ,
title : 1 ,
by_user : 1
}});
{ "title" : "MongoDB 教程", "by_user" : "小罗" }
{ "title" : "MongoDB 教程", "by_user" : "小罗" }
{ "title" : "MongoDB 教程", "by_user" : "小罗" }
2.$match实例
db.col.aggregate( [
{ $match : { likes : { $gt : 90, $lte : 200 } } },
{ $group: { _id: null, count: { $sum: 1 } } }
] );
match用于获取likes大于70小于或等于90记录,然后将符合条件的记录送到下一阶段
group管道操作符进行处理。
MongoDB Enterprise > db.col.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])
{ "_id" : "penglei", "num_tutorial" : 3 }
MongoDB Enterprise >
以上实例类似sql语句:
select by_user as _id, count(*) as num_tutorial from mycol group by by_user
按日、按月、按年、按周、按小时、按分钟聚合操作如下:
db.getCollection('m_msg_tb').aggregate(
[
{$match:{m_id:10001,mark_time:{$gt:new Date(2017,8,0)}}},
{$group: {
_id: {$dayOfMonth:'$mark_time'},
pv: {$sum: 1}
}
},
{$sort: {"_id": 1}}
])
时间关键字如下:
$dayOfYear: 返回该日期是这一年的第几天(全年 366 天)。
$dayOfMonth: 返回该日期是这一个月的第几天(1到31)。
$dayOfWeek: 返回的是这个周的星期几(1:星期日,7:星期六)。
$year: 返回该日期的年份部分。
$month: 返回该日期的月份部分( 1 到 12)。
$week: 返回该日期是所在年的第几个星期( 0 到 53)。
$hour: 返回该日期的小时部分。
$minute: 返回该日期的分钟部分。
$second: 返回该日期的秒部分(以0到59之间的数字形式返回日期的第二部分,但可以是60来计算闰秒)。
$millisecond:返回该日期的毫秒部分( 0 到 999)。
$dateToString: { $dateToString: { format: , date: } }。