MongoDB高级操作
参考MongoDB菜鸟教程
一、$type操作符
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 |
如果想获取 "col" 集合中 title 为 String 的数据,你可以使用以下命令:
db.col.find({"title" : {$type : 2}})
二、Limit()
如果你需要在MongoDB中读取指定数量的数据记录,可以使用MongoDB的Limit方法,limit()方法接受一个数字参数,该参数指定从MongoDB中读取的记录条数。
语法格式
>db.COLLECTION_NAME.find().limit(NUMBER)
实例用法
> db.col.find({},{"title":1,_id:0}).limit(2)
{ "title" : "PHP 教程" }
{ "title" : "Java 教程" }
>
注:如果你们没有指定limit()方法中的参数则显示集合中的所有数据。
三、Skip()
我们除了可以使用limit()方法来读取指定数量的数据外,还可以使用skip()方法来跳过指定数量的数据,skip方法同样接受一个数字参数作为跳过的记录条数。
语法格式
>db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
实例用法
>db.col.find({},{"title":1,_id:0}).limit(1).skip(1)
{ "title" : "Java 教程" }
>
表示跳过第一条文档,且只返回一条文档数据。注意skip()方法默认参数为0。
四、sort()
使用sort()对数据进行排序,参数为1或者-1,其中1为升序排列,-1为降序排列。
语法格式
>db.COLLECTION_NAME.find().sort({KEY:1})
说明:KEY表示对其进行排序的字段
五、索引
使用 ensureIndex() 方法来创建索引
>db.COLLECTION_NAME.ensureIndex({KEY:1})
语法中 Key 值为你要创建的索引字段,1为指定按升序创建索引,如果你想按降序来创建索引指定为-1即可。
ensureIndex() 接收可选参数,可选参数列表如下:
Parameter | Type | Description |
---|---|---|
background | Boolean | 建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 "background" 可选参数。 "background" 默认值为false。 |
unique | Boolean | 建立的索引是否唯一。指定为true创建唯一索引。默认值为false. |
name | string | 索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。 |
dropDups | Boolean | 在建立唯一索引时是否删除重复记录,指定 true 创建唯一索引。默认值为 false. |
sparse | Boolean | 对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档.。默认值为 false. |
expireAfterSeconds | integer | 指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间。 |
v | index version | 索引的版本号。默认的索引版本取决于mongod创建索引时运行的版本。 |
weights | document | 索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。 |
default_language | string | 对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语 |
language_override | string | 对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为 language. |
六、MongoDB聚合
aggregate()方法,主要用于处理数据,如统计平均值、求和等,并返回计算后的数据结果。
语法格式
>db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
实例
假设集合中数据如下
{
_id: ObjectId(7df78ad8902c)
title: 'MongoDB Overview',
description: 'MongoDB is no sql database',
by_user: 'w3cschool.cc',
url: 'http://www.w3cschool.cc',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
},
{
_id: ObjectId(7df78ad8902d)
title: 'NoSQL Overview',
description: 'No sql database is very fast',
by_user: 'w3cschool.cc',
url: 'http://www.w3cschool.cc',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 10
},
{
_id: ObjectId(7df78ad8902e)
title: 'Neo4j Overview',
description: 'Neo4j is no sql database',
by_user: 'Neo4j',
url: 'http://www.neo4j.com',
tags: ['neo4j', 'database', 'NoSQL'],
likes: 750
},
现在我们通过以上集合计算每个作者所写的文章数,使用aggregate()计算结果如下:
> db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}]) // increment num_tutorial for each document
{
"result" : [
{
"_id" : "w3cschool.cc",
"num_tutorial" : 2
},
{
"_id" : "Neo4j",
"num_tutorial" : 1
}
],
"ok" : 1
}
>
以上实例类似sql语句: select by_user, count(*) from mycol group by by_user
在上面的例子中,我们通过字段by_user字段对数据进行分组,并计算by_user字段相同值的总和。
下表展示了一些聚合的表达式:
表达式 | 描述 | 实例 |
---|---|---|
$sum | 计算总和。 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}]) |
$avg | 计算平均值 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}]) |
$min | 获取集合中所有文档对应值得最小值。 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}]) |
$max | 获取集合中所有文档对应值得最大值。 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}]) |
$push | 在结果文档中插入值到一个数组中。 | db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}]) |
$addToSet | 在结果文档中插入值到一个数组中,但不创建副本。 | db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}]) |
$first | 根据资源文档的排序获取第一个文档数据。 | db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}]) |
$last | 根据资源文档的排序获取最后一个文档数据 | db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}]) |
聚合管道
在聚合管道中,每一步操作(管道操作符)都是一个工作阶段(stage),所有的stage存放在一个array中。MongoDB文档中的描述如下:
db.collection.aggregate( [ { <stage> }, ... ] )
在聚合管道中,每一个stage都对应一个管道操作符,根据MongoDB文档,聚合管道可以支持以下管道操作符:
Name |
Description |
$geoNear |
Returns an ordered stream of documents based on the proximity to a geospatial point. Incorporates the functionality of $match, $sort, and $limit for geospatial data. The output documents include an additional distance field and can include a location identifier field. |
$group |
Groups input documents by a specified identifier expression and applies the accumulator expression(s), if specified, to each group. Consumes all input documents and outputs one document per each distinct group. The output documents only contain the identifier field and, if specified, accumulated fields. |
$limit |
Passes the first n documents unmodified to the pipeline where n is the specified limit. For each input document, outputs either one document (for the first n documents) or zero documents (after the first n documents). |
$match |
Filters the document stream to allow only matching documents to pass unmodified into the next pipeline stage. $match uses standard MongoDB queries. For each input document, outputs either one document (a match) or zero documents (no match). |
$out |
Writes the resulting documents of the aggregation pipeline to a collection. To use the $out stage, it must be the last stage in the pipeline. |
$project |
Reshapes each document in the stream, such as by adding new fields or removing existing fields. For each input document, outputs one document. |
$redact |
Reshapes each document in the stream by restricting the content for each document based on information stored in the documents themselves. Incorporates the functionality of $project and $match. Can be used to implement field level redaction. For each input document, outputs either one or zero document. |
$skip |
Skips the first n documents where n is the specified skip number and passes the remaining documents unmodified to the pipeline. For each input document, outputs either zero documents (for the first n documents) or one document (if after the first n documents). |
$sort |
Reorders the document stream by a specified sort key. Only the order changes; the documents remain unmodified. For each input document, outputs one document. |
$unwind |
Deconstructs an array field from the input documents to output a document for each element. Each output document replaces the array with an element value. For each input document, outputs n documents where n is the number of array elements and can be zero for an empty array. |
实例演示1
1.$project
db.article.aggregate(
{ $project : {
title : 1 , // 包含"title"字段
author : 1 , // 包含"author"字段
}}
);
这样的话结果中就只还有_id,tilte和author三个字段了,默认情况下_id字段是被包含的,如果要想不包含_id话可以这样:
db.article.aggregate(
{ $project : {
_id : 0 ,
title : 1 ,
author : 1
}});
2.$match
db.articles.aggregate( [
{ $match : { score : { $gt : 70, $lte : 90 } } }, // 第一个管道符
{ $group: { _id: null, count: { $sum: 1 } } } // 第二个管道符
] );
$match用于获取分数大于70小于或等于90记录,然后将符合条件的记录送到下一阶段$group管道操作符进行处理。
3.$skip
db.article.aggregate(
{ $skip : 5 });
经过$skip管道操作符处理后,前五个文档被"过滤"掉。
实例演示2
首先,通过以下代码准备测试数据:
1 var dataList = [
2 { "name" : "Will0", "gender" : "Female", "age" : 22 , "classes": ["MongoDB", "C#", "C++"]},
3 { "name" : "Will1", "gender" : "Female", "age" : 20 , "classes": ["Node", "JavaScript"]},
4 { "name" : "Will2", "gender" : "Male", "age" : 24 , "classes": ["Java", "WPF", "C#"]},
5 { "name" : "Will3", "gender" : "Male", "age" : 23 , "classes": ["WPF", "C",]},
6 { "name" : "Will4", "gender" : "Male", "age" : 21 , "classes": ["SQL", "HTML"]},
7 { "name" : "Will5", "gender" : "Male", "age" : 20 , "classes": ["DOM", "CSS", "HTML5"]},
8 { "name" : "Will6", "gender" : "Female", "age" : 20 , "classes": ["PPT", "Word", "Excel"]},
9 { "name" : "Will7", "gender" : "Female", "age" : 24 , "classes": ["HTML5", "C#"]},
10 { "name" : "Will8", "gender" : "Male", "age" : 21 , "classes": ["Java", "VB", "BASH"]},
11 { "name" : "Will9", "gender" : "Female", "age" : 24 , "classes": ["CSS"]}
12 ]
13
14 for(var i = 0; i < dataList.length; i++){
15 db.school.students.insert(dataList[i]);
16 }
$project
$project主要用于数据投影,实现字段的重命名、增加和删除。下面例子中,重命名了"name"字段,增加了"birthYear"字段,删除了"_id"字段。
1 > db.runCommand({
2 ... "aggregate": "school.students",
3 ... "pipeline": [
4 ... {"$match": {"age": {"$lte": 22}}},
5 ... {"$project": {"_id": 0, "studentName": "$name", "gender": 1, "birthYear": {"$subtract": [2014, "$age"]}}},
6 ... {"$sort": {"birthYear":1}}
7 ... ]
8 ... })
9 {
10 "result" : [
11 {
12 "gender" : "Female",
13 "studentName" : "Will0",
14 "birthYear" : 1992
15 },
16 {
17 "gender" : "Male",
18 "studentName" : "Will4",
19 "birthYear" : 1993
20 },
21 {
22 "gender" : "Male",
23 "studentName" : "Will8",
24 "birthYear" : 1993
25 },
26 {
27 "gender" : "Female",
28 "studentName" : "Will1",
29 "birthYear" : 1994
30 },
31 {
32 "gender" : "Male",
33 "studentName" : "Will5",
34 "birthYear" : 1994
35 },
36 {
37 "gender" : "Female",
38 "studentName" : "Will6",
39 "birthYear" : 1994
40 }
41 ],
42 "ok" : 1
43 }
44 >
$unwind
$unwind用来将数组拆分为独立字段。
1 > db.runCommand({
2 ... "aggregate": "school.students",
3 ... "pipeline": [
4 ... {"$match": {"age": 23}},
5 ... {"$project": {"name": 1, "gender": 1, "age": 1, "classes": 1}},
6 ... {"$unwind": "$classes"}
7 ... ]
8 ... })
9 {
10 "result" : [
11 {
12 "_id" : ObjectId("54805220e31c9e1578ed0ccc"),
13 "name" : "Will3",
14 "gender" : "Male",
15 "age" : 23,
16 "classes" : "WPF"
17 },
18 {
19 "_id" : ObjectId("54805220e31c9e1578ed0ccc"),
20 "name" : "Will3",
21 "gender" : "Male",
22 "age" : 23,
23 "classes" : "C"
24 }
25 ],
26 "ok" : 1
27 }
28 >
$group
跟单个的group用法类似,用作分组操作。
使用$group时,必须要指定一个_id域,同时也可以包含一些算术类型的表达式操作符。
下面的例子就是用聚合管道实现得到男生和女生的平均年龄。
1 > db.runCommand({
2 ... "aggregate": "school.students",
3 ... "pipeline": [
4 ... {"$group":{"_id":"$gender", "avg": { "$avg": "$age" } }}
5 ... ]
6 ... })
7 {
8 "result" : [
9 {
10 "_id" : "Male",
11 "avg" : 21.8
12 },
13 {
14 "_id" : "Female",
15 "avg" : 22
16 }
17 ],
18 "ok" : 1
19 }
20 >
查询男生和女生的最大年龄
1 > db.runCommand({
2 ... "aggregate": "school.students",
3 ... "pipeline": [
4 ... {"$group": {"_id": "$gender", "max": {"$max": "$age"}}}
5 ... ]
6 ... })
7 {
8 "result" : [
9 {
10 "_id" : "Male",
11 "max" : 24
12 },
13 {
14 "_id" : "Female",
15 "max" : 24
16 }
17 ],
18 "ok" : 1
19 }
20 >
管道操作符、管道表达式和表达式操作符
上面的例子中,已经接触了这几个概念,下面进行进一步介绍。
管道操作符作为"键",所对应的"值"叫做管道表达式,例如"{"$group": {"_id": "$gender", "max": {"$max": "$age"}}}"
- $group是管道操作符
- {"_id": "$gender", "max": {"$max": "$age"}}是管道表达式
- $gender在文档中叫做"field path",通过"$"符号来获得特定字段,是管道表达式的一部分
- $max是表达式操作符,正是因为聚合管道中提供了很多表达式操作符,我们可以省去很多自定义js函数
下面列出了常用的表达式操作符,更详细的信息,请参阅MongoDB文档
- Boolean Expressions
- $and, $or, $ not
- Comparison Expressions
- $cmp, $eq, $gt, $gte, $lt, $lte, $ne
- Arithmetic Expressions
- $add, $divide, $mod, $multiply, $subtract
- String Expressions
- $concat, $strcasecmp, $substr, $toLower, $toUpper
总结
聚合管道提供了一种mapReduce 的替代方案,mapReduce使用相对来说比较复杂,而聚合管道的拥有固定的接口,一系列可选择的表达式操作符,对于大多数的聚合任务,聚合管道一般来说是首选方法。
Ps: 聚合管道中使用的例子可以通过以下链接查看
http://files.cnblogs.com/wilber2013/pipeline.js
MongoDB高级操作的更多相关文章
- mongodb高级操作及在Java企业级开发中的应用
Java连接mongoDB Java连接MongoDB需要驱动包,个人所用包为mongo-2.10.0.jar.可以在网上下载最新版本. package org.dennisit.mongodb.st ...
- mongodb 高级操作
聚合 aggregate 聚合(aggregate)主要用于计算数据,类似sql中的sum().avg() 语法 db.集合名称.aggregate([{管道:{表达式}}]) 管道 管道在Unix和 ...
- MongoDB高级操作(2)
查询方法-常用查询方法 查询多条数据 --db.集合名称.find({条件文档}) 查询一条数据 --db.集合名称.findOne({条件文档}) 结果格式化 --pretty()方法 --db.集 ...
- SpringMVC整合Mongodb开发,高级操作
开发环境: 操作系统:windows xpMongodb:2.0.6依 赖 包:Spring3.2.2 + spring-data-mongodb-1.3.0 + Spring-data-1.5 + ...
- mongodb常用操作语句
mongodb常用操作语句 A:创建数据表 db.createCollection(name, {capped: <Boolean>, autoIndexId: <Boolean&g ...
- MongoDB高级查询用法大全
转载 http://blog.163.com/lgh_2002/blog/static/440175262012052116455/ 详见官方的手册: http://www.mongodb.org/d ...
- DataBase MongoDB高级知识
MongoDB高级知识 一.mongodb适合场景: 1.读写分离:MongoDB服务采用三节点副本集的高可用架构,三个数据节点位于不同的物理服务器上,自动同步数据.Primary和Secondary ...
- Mongodb高级查询【二】
上一篇文章,写了mongodb常规操作,继续写入,本章主要讲高级查询,文本,聚集,大数据查询. Mongodb的查询语法是很多的,是NOSQL队伍中比较丰富的一个.当然有很多查询跟关系型查询无法相比. ...
- mongoDB高级查询$type4array使用解析
今天在使用mongoDB高级查询$type:符号 -- 4代指Array类型发现一个问题. $type符号: $type操作符是基于BSON类型来检索集合中匹配的数据类型,并返回结果. 下面是mong ...
随机推荐
- hdu 2824 The Euler function(欧拉函数)
题目链接:hdu 2824 The Euler function 题意: 让你求一段区间的欧拉函数值. 题解: 直接上板子. 推导过程: 定义:对于正整数n,φ(n)是小于或等于n的正整数中,与n互质 ...
- Android平台 视频编辑的高级版本
基本覆盖了秒拍,美拍,快手等视频编辑的大部分功能. 增加了44种滤镜,基本覆盖市面上大部分APP中的滤镜效果. 可以实现视频和视频, 视频和图片,视频和您的UI界面叠加. 在叠加的过程中:支持任意时间 ...
- 获取Java的32位MD5实现
获取Java的32位MD5实现 public static String md5(String s) { char hexDigits[] = {'0','1','2','3','4','5','6' ...
- 51nod1092(lcs简单运用/dp)
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1092 题意:中文题诶- 思路: 解法1:最坏的情况就是在原字 ...
- Abstraction elimination
(本文不保证不误人子弟,切勿轻信) Unlambda指的是lambda计算中去掉lambda操作(does not have lambda(or abstraction) operation of t ...
- Python基础(十)-模块
模块初识 一般把不同功能代码放到不同py文件,一个py文件就是一个模块 三种模块库: 1.Python标准库 2.第三方库 3.自定义库 导入模块:import 库名 (Python解释器只认识执行文 ...
- removeObjectAtIndex
CGFloat lableW = (baseViewWidth - 2)/3;// dcj20150724,减2是为了解决字体模糊的问题,因为设置了边框. 原因是下面引起的 titleview.lay ...
- 解决gstreamer无法播放的bug
0 ls 1 ./start.sh 2 ps 3 kill 366 4 cd /usr/app/services/ 5 ./start.sh 6 cd ../ 7 ls 8 cd res/ 9 ls ...
- angular中的jsonp记录
angular的正常机制采用引入$http服务的形式进行 get post等的访问.但是在跨域访问的时候就需要采用jsonp了. 不废话,直接上示例和引用原文地址: 比如访问地址为 http://ur ...
- 8. Shell 文件包含
1. 语法 . filename # 注意点号(.)和文件名中间有一空格 或 source filename ### test.sh #!/bin/bash url="www.baidu.c ...