MongoDB 常用命令操作 集合 元数据 数据类型
一、集合
集合就是 MongoDB 文档组,类似于 RDBMS (关系数据库管理系统:Relational Database Management System)中的表格。
集合存在于数据库中,集合没有固定的结构,这意味着你在对集合可以插入不同格式和类型的数据,但通常情况下我们插入集合的数据都会有一定的关联性。
在 test 数据库中创建 runoob 集合:
> use test
switched to db test
> db.createCollection("runoob")
{ "ok" : 1 }
>
如果要查看已有集合,可以使用 show collections 或 show tables 命令:
> show collections
runoob
system.indexes
比如,我们可以将以下不同数据结构的文档插入到集合中:
# 当第一个文档插入时,集合就会被自动创建。
> db.mycol222.insert({"name" : "菜鸟教程"})
> show collections
mycol222
...
合法的集合名
集合名不能是空字符串""。
集合名不能含有\0字符(空字符),这个字符表示集合名的结尾。
集合名不能以"system."开头,这是为系统集合保留的前缀。
用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。除非你要访问这种系统创建的集合,否则千万不要在名字里出现$。
二、元数据
数据库的信息是存储在集合中。它们使用了系统的命名空间:
dbname.system.*
在MongoDB数据库中名字空间
集合命名空间 | 描述 |
---|---|
dbname.system.namespaces | 列出所有名字空间。 |
dbname.system.indexes | 列出所有索引。 |
dbname.system.profile | 包含数据库概要(profile)信息。 |
dbname.system.users | 列出所有可访问数据库的用户。 |
dbname.local.sources | 包含复制对端(slave)的服务器信息和状态。 |
对于修改系统集合中的对象有如下限制。
在{{system.indexes}}插入数据,可以创建索引。但除此之外该表信息是不可变的(特殊的drop index命令将自动更新相关信息)。
{{system.users}}是可修改的。 {{system.profile}}是可删除的。
三、MongoDB 数据类型
下表为MongoDB中常用的几种数据类型。
数据类型 | 描述 |
---|---|
String | 字符串。存储数据常用的数据类型。在 MongoDB 中,UTF-8 编码的字符串才是合法的。 |
Integer | 整型数值。用于存储数值。根据你所采用的服务器,可分为 32 位或 64 位。 |
Boolean | 布尔值。用于存储布尔值(真/假)。 |
Double | 双精度浮点值。用于存储浮点值。 |
Min/Max keys | 将一个值与 BSON(二进制的 JSON)元素的最低值和最高值相对比。 |
Array | 用于将数组或列表或多个值存储为一个键。 |
Timestamp | 时间戳。记录文档修改或添加的具体时间。 |
Object | 用于内嵌文档。 |
Null | 用于创建空值。 |
Symbol | 符号。该数据类型基本上等同于字符串类型,但不同的是,它一般用于采用特殊符号类型的语言。 |
Date | 日期时间。用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间:创建 Date 对象,传入年月日信息。 |
Object ID | 对象 ID。用于创建文档的 ID。 |
Binary Data | 二进制数据。用于存储二进制数据。 |
Code | 代码类型。用于在文档中存储 JavaScript 代码。 |
Regular expression | 正则表达式类型。用于存储正则表达式。 |
下面说明下几种重要的数据类型。
1.主键 ObjectId
ObjectId 类似唯一主键,可以很快的去生成和排序,包含 12 bytes,含义是:
- 前 4 个字节表示创建 unix 时间戳,格林尼治时间 UTC 时间,比北京时间晚了 8 个小时
- 接下来的 3 个字节是机器标识码
- 紧接的两个字节由进程 id 组成 PID
- 最后三个字节是随机数
MongoDB 中存储的文档必须有一个 _id 键。这个键的值可以是任何类型的,默认是个 ObjectId 对象
由于 ObjectId 中保存了创建的时间戳,所以你不需要为你的文档保存时间戳字段,你可以通过 getTimestamp 函数来获取文档的创建时间:
> var newObject = ObjectId()
> newObject.getTimestamp()
ISODate("2017-11-25T07:21:10Z")
ObjectId 转为字符串
> newObject.str
5a1919e63df83ce79df8b38f
2.字符串
BSON 字符串都是 UTF-8 编码。
3.时间戳
BSON 有一个特殊的时间戳类型用于 MongoDB 内部使用,与普通的 日期 类型不相关。 时间戳值是一个 64 位的值。其中:
- 前32位是一个 time_t 值(与Unix新纪元相差的秒数)
- 后32位是在某秒中操作的一个递增的
序数
在单个 mongod 实例中,时间戳值通常是唯一的。
在复制集中, oplog 有一个 ts 字段。这个字段中的值使用BSON时间戳表示了操作时间。
BSON 时间戳类型主要用于 MongoDB 内部使用。在大多数情况下的应用开发中,你可以使用 BSON 日期类型。
4.日期
表示当前距离 Unix新纪元(1970年1月1日)的毫秒数。日期类型是有符号的, 负数表示 1970 年之前的日期。
> var mydate1 = new Date() //格林尼治时间
> mydate1
ISODate("2018-03-04T14:58:51.233Z")
> typeof mydate1
object
> var mydate2 = ISODate() //格林尼治时间
> mydate2
ISODate("2018-03-04T15:00:45.479Z")
> typeof mydate2
object
这样创建的时间是日期类型,可以使用 JS 中的 Date 类型的方法。
返回一个时间类型的字符串:
> var mydate1str = mydate1.toString()
> mydate1str
Sun Mar 04 2018 14:58:51 GMT+0000 (UTC)
> typeof mydate1str
string
或者
> Date()
Sun Mar 04 2018 15:02:59 GMT+0000 (UTC)
四、基本操作
1.操作说明
启动:
[mongo@db02 ~]mongod -f /server/mongo_27017/conf/mongodb.conf
[mongo@db02 ~] mongo
CRUD操作是create(创建), read(读取), update(更新)和delete(删除) 文档。
MongoDB不支持SQL但是支持自己的丰富的查询语言。
在MongoDB中,存储在集合中的每个文档都需要一个唯一的 _id字段,作为主键。如果插入的文档省略了该_id字段,则MongoDB驱动程序将自动为该字段生成一个ObjectId_id。也用于通过更新操作插入的文档upsert: true.如果文档包含一个_id字段,该_id值在集合中必须是唯一的,以避免重复键错误。
在MongoDB中,插入操作针对单个集合。 MongoDB中的所有写操作都是在单个文档的级别上进行的
由于它是一个JavaScript shell,您可以运行一些简单的算术运算:
> 2+2
4
> 3+6
9
2.基本操作
show databases/show dbs #查看库列表
show tables/show collections #查看所有的集合
use admin #切换库(没有的库也可以进行切换,没有数据是看不到)
db #查看当前库
show users #打印当前数据库的用户列表
test:登录时默认存在的库
admin库:系统预留库,MongoDB系统管理库
local库:本地预留库,存储关键日志
config库:MongoDB配置信息库
- db 对象相关命令
db.[TAB][TAB]
db.help()
db.oldboy.[TAB][TAB]
db.oldboy.help()
- rs 复制集有关(replication set):
rs.[TAB][TAB]
rs.help()
- sh 分片集群(sharding cluster)
sh.[TAB][TAB]
sh.help()
- 官方文档
https://docs.mongodb.com/manual
mongodb默认help比较简介,推荐查看详细的官方文档.
3.插入数据
1)单条数据插入
db.test.insert({"name":"lhd","age":18,"sex":"男"})
db.test.insert({"name":"lhd","age":18,"sex":"男","address":"上海浦东新区"})
db.test.insertOne({"name":"lhd","age":18,"sex":"男","address":"上海浦东新区"})
2)多条数据插入
db.inventory.insertMany( [
{ "name": "lhd", "age": 18, "figure": { "h": 182, "w": 200 }, "size": "big" },
{ "name": "qiudao", "age": 88, "figure": { "h": 120, "w": 160 }, "size": "very bittle" },
{ "name": "zengdao", "age": 18, "figure": { "h": 180, "w": 160 }, "size": "nomel" }
])
#在需要换行的后面使用 shift+enter就能启动命令行换行模式了,之后输入直接按Enter就可以换行,最后用Ctrl+Enter才能执行语句。
==================
# insertMany和insertOne不能执行db.collection.explain() 查询计划
# insert 可以替代 insertMany和insertOne
4.查询数据
# MongoDB 查询数据的语法格式如下:
> db.collection.find(query, projection)
query :可选,使用查询操作符指定查询条件
projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。
'如果你需要以易读的方式来读取数据,可以使用 pretty() 方法以格式化的方式来显示所有文档,语法格式如下:'
> db.col.find().pretty()
> db.users.find({},{projection})
#注意:{}实现的是筛选出某条数据,projection实现的是筛选出某条数据的具体字段.
不显示:false 或 0
显示:true 或 1
#默认显示_id信息和指定为显示的信息,其他都不显示。
#筛选指定信息,不显示_id字段
> db.users.find({},{_id:false})
或者db.users.find({},{_id:0})
例如:以下实例为显示查询文档中的指定记录:
================
> db.ccc.find()
{ "_id" : ObjectId("5fa12732cc41619570ae6bb8"), "name" : "lhd", "age" : 18, "figure" : { "h" : 182, "w" : 200 }, "size" : "big" }
{ "_id" : ObjectId("5fa12732cc41619570ae6bb9"), "name" : "qiudao", "age" : 88, "figure" : { "h" : 120, "w" : 160 }, "size" : "very bittle" }
{ "_id" : ObjectId("5fa12732cc41619570ae6bba"), "name" : "zengdao", "age" : 18, "figure" : { "h" : 180, "w" : 160 }, "size" : "nomel" }
> db.ccc.find({},{"name":1,"age":1,_id:0})
{ "name" : "lhd", "age" : 18 }
{ "name" : "qiudao", "age" : 88 }
{ "name" : "zengdao", "age" : 18 }
1)查询所有数据
> db.test.find()
{ "_id" : ObjectId("5ecdcdac13a4155a65ecb332"), "name" : "lhd", "age" : 18, "sex" : "男" }
{ "_id" : ObjectId("5ecdcdc413a4155a65ecb333"), "name" : "lhd", "age" : 18, "sex" : "男", "address" : "上海浦东新区" }
{ "_id" : ObjectId("5ecdcdd213a4155a65ecb334"), "name" : "lhd", "age" : 18, "sex" : "男" }
{ "_id" : ObjectId("5ecdcdd813a4155a65ecb335"), "name" : "lhd", "age" : 18, "sex" : "男", "address" : "上海浦东新区" }
2)查询单条数据
> db.test.findOne()
{
"_id" : ObjectId("5ecdcdac13a4155a65ecb332"),
"name" : "lhd",
"age" : 18,
"sex" : "男"
}
3)按条件查询
#如果查询条件为数字,不需要加引号
> db.test.findOne({"name" : "lhd"})
{
"_id" : ObjectId("5ecdcdac13a4155a65ecb332"),
"name" : "lhd",
"age" : 18,
"sex" : "男"
}
# 也可以用find直接查询
4)查询多条件
#并且的多个条件查询
> db.inventory.find({"figure.h":120,"size":"very bittle"})
> db.inventory.find(
{
"figure.h":120,
"size":"very bittle"
}
)
#表示多条件或者 or
> db.inventory.find({or:[{"figure.h":120},{"size":"big"}]})
> db.inventory.find(
{
$or:[
{"figure.h":120},
{"size":"big"}
]
}
)
5)条件加范围的查询
# 条件操作符
(>) 大于 - gt
(<) 小于 -lt
(>=) 大于等于 - gte
(<=) 小于等于 -lte
例如: 小于 lt
> db.inventory.find({or:[{"figure.h":{lt:130}},{"size":"big"}]})
> db.inventory.find(
{or:[
{"figure.h":{$lt:130}},
{"size":"big"}
]
}
)
6)$type操作符
$type操作符是基于BSON类型来检索集合中匹配的数据类型,并返回结果。
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 |
我们使用的数据库名称为"runoob" 我们的集合名称为"col",以下为我们插入的数据。
简单的集合"col":
>db.col.insert({
title: 'PHP 教程',
description: 'PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。',
by: '菜鸟教程',
url: 'http://www.runoob.com',
tags: ['php'],
likes: 200
})
>db.col.insert({title: 'Java 教程',
description: 'Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。',
by: '菜鸟教程',
url: 'http://www.runoob.com',
tags: ['java'],
likes: 150
})
>db.col.insert({title: 'MongoDB 教程',
description: 'MongoDB 是一个 Nosql 数据库',
by: '菜鸟教程',
url: 'http://www.runoob.com',
tags: ['mongodb'],
likes: 100
})
使用find()命令查看数据:
> db.col.find()
{ "_id" : ObjectId("56066542ade2f21f36b0313a"), "title" : "PHP 教程", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "php" ], "likes" : 200 }
{ "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 }
{ "_id" : ObjectId("5606654fade2f21f36b0313c"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb" ], "likes" : 100 }
获取数据
## MongoDB 操作符 - type 实例
如果想获取 "col" 集合中 title 为 String 的数据,你可以使用以下命令:
db.col.find({"title" : {type : 2}})
或
db.col.find({"title" : {$type : 'string'}})
输出结果为:
{ "_id" : ObjectId("56066542ade2f21f36b0313a"), "title" : "PHP 教程", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "php" ], "likes" : 200 }
{ "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 }
{ "_id" : ObjectId("5606654fade2f21f36b0313c"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb" ], "likes" : 100 }
6) Limit与Skip方法
#limit()方法基本语法如下所示:
> db.COLLECTION_NAME.find().limit(NUMBER)
如果你们没有指定limit()方法中的参数则显示集合中的所有数据。
> db.col.find({},{"title":1,_id:0}).limit(2)
{ "title" : "PHP 教程" }
{ "title" : "Java 教程" }
# 使用skip()方法来跳过指定数量的数据
skip() 方法脚本语法格式如下:
> db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
注:skip()方法默认参数为 0 。
实例
以下实例会跳过结果第一条显示第二条文档数据
> db.col.find({},{"title":1,_id:0}).limit(1).skip(1)
{ "title" : "Java 教程" }
>
5.修改数据
1)修改单个数据 $set
# 先使用查找的方式找到数据,然后set去修改.
> db.inventory.updateOne({"name":"qiudao"},{set:{"figure.h":130}})
> db.inventory.updateOne(
#条件
{"name":"qiudao"},
{
$set:
#修改的值
{"figure.h":130}
}
)
6.索引
1)查看执行计划
> db.inventory.find().explain()
{ #查询计划
"queryPlanner" : {
#计划版本
"plannerVersion" : 1,
#被查询的库和集合
"namespace" : "test2.inventory",
#查询索引设置
"indexFilterSet" : false,
#查询条件
"parsedQuery" : {
},
#成功的执行计划
"winningPlan" : {
#全表扫描
"stage" : "COLLSCAN",
#查询方向
"direction" : "forward"
},
#拒绝的计划
"rejectedPlans" : [ ]
},
#服务器信息
"serverInfo" : {
"host" : "redis01",
"port" : 27017,
"version" : "3.6.13",
"gitVersion" : "db3c76679b7a3d9b443a0e1b3e45ed02b88c539f"
},
"ok" : 1
}
COLLSCAN 全表扫描
IXSCAN 索引扫描
2)创建索引
> db.inventory.createIndex({"age":1},{background:true})
结果:ok表示成功
{
"createdCollectionAutomatically" : true,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
#添加索引
createIndex({索引的名称:1}) :1表示正序,-1表示倒序
创建索引是否自动排序的一个属性,一般是false,因为在它下面都会设置好排序方式。
createdCollectionAutomatically
#创建方式
1.前台方式
缺省情况下,当为一个集合创建索引时,这个操作将阻塞其他的所有操作。即该集合上的无法正常读写,直到索引创建完毕
任意基于所有数据库申请读或写锁都将等待直到前台完成索引创建操作
2.后台方式
将索引创建置于到后台,适用于那些需要长时间创建索引的情形
这样子在创建索引期间,MongoDB依旧可以正常的为提供读写操作服务
等同于关系型数据库在创建索引的时候指定online,而MongoDB则是指定background
其目的都是相同的,即在索引创建期间,尽可能的以一种占用较少的资源占用方式来实现,同时又可以提供读写服务
后台创建方式的代价:索引创建时间变长
#规范
1.如果要查询的内容都是最近的,那建立索引就用倒序,如果要通盘查询那就用正序。
2.比如说一个数据集合查询占的比较多就用索引,如果查询少而是插入数据比较多就不用建立索引。因为:当没有索引的时候,插入数据的时候MongoDB会在内存中分配出一块空间,用来存放数据。当有索引的时候在插入数据之后还会给自动添加一个索引,浪费了时间。
3.不是所有数据都要建立索引,要在恰当并且需要的地方建立才是最好的。
4.大数量的排序工作时可以考虑创建索引。
- createIndex() 方法中也可以设置使用多个字段创建索引(关系型数据库中称作复合索引)。
> db.col.createIndex({"title":1,"description":-1})
- createIndex() 接收可选参数,可选参数列表如下:
Parameter | Type | Description |
---|---|---|
background | Boolean | 建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 "background" 可选参数。 "background" 默认值为false。 |
unique | Boolean | 建立的索引是否唯一。指定为true创建唯一索引。默认值为false. |
name | string | 索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。 |
dropDups | Boolean | 3.0+版本已废弃。在建立唯一索引时是否删除重复记录,指定 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. |
3) 各种索引的创建
# 1.为普通字段添加索引,并且为索引命名(name)
db.集合名.createIndex( {"字段名": 1 },{"name":'idx_字段名'})
说明:
(1)索引命名规范:idx_<构成索引的字段名>。如果字段名字过长,可采用字段缩写。
(2)字段值后面的 1 代表升序;如是 -1 代表 降序。
# 2.为内嵌字段添加索引
db.集合名.createIndex({"字段名.内嵌字段名":1},{"name":'idx_字段名_内嵌字段名'})
# 3.通过后台创建索引
db.集合名.createIndex({"字段名":1},{"name":'idx_字段名',background:true})
# 4:组合索引
db.集合名.createIndex({"字段名1":-1,"字段名2":1},{"name":'idx_字段名1_字段名2',background:true})
# 5.设置TTL 索引
db.集合名.createIndex( { "字段名": 1 },{ "name":'idx_字段名',expireAfterSeconds: 定义的时间,background:true} )
说明 :expireAfterSeconds为过期时间(单位秒)
'TTL索引是一种特殊类型的单字段索引,主要用于当满足某个特定时间之后自动删除相应的文档。也就是说集合中的文档有一定的有效期,超过有效期的文档就会失效,会被移除。也即是数据会过期。过期的数据无需保留,这种情形适用于如机器生成的事件数据,日志和会话信息等等。'
4)查看索引
MongoDB提供了查看索引信息的方法:getIndexes()方法可以用来查看集合的所有索引,totalIndexSize()查看集合索引的总大小,db.system.indexes.find()查看数据库中所有索引信息。
1. 查看集合中的索引getIndexes()
db.COLLECTION_NAME.getIndexes()
如,查看集合sites中的索引:
>db.sites.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "newDB.sites"
},
{
"v" : 1,
"key" : {
"name" : 1,
"domain" : -1
},
"name" : "name_1_domain_-1",
"ns" : "newDB.sites"
}
]
2. 查看集合中的索引大小totalIndexSize()
db.COLLECTION_NAME.totalIndexSize()
如,查看集合sites索引大小:
> db.sites.totalIndexSize()
16352
3. 查看数据库中所有索引db.system.indexes.find()
db.system.indexes.find()
如,当前数据库的所有索引:
> db.system.indexes.find()
# 再次查看执行计划
> db.inventory.find({"age":{$lt:40}}).explain()
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
#走索引了
"stage" : "IXSCAN",
7.删除
1)删除单条数据
> db.inventory.deleteOne({"name":"lhd"})
{ "acknowledged" : true, "deletedCount" : 1 }
2)删除多个数据
> db.inventory.deleteMany({"name":"lhd"})
'注意: 删除记录不释放空间:这很容易理解,为避免记录删除后的数据的大规模挪动,原记录空间不删除,只标记“已删除”即可,以后还可以重复利用。'
# 可以定期运行db.repairDatabase()来整理记录,但这个过程会比较缓慢
3)删除索引
=====错误=====
> db.test.dropIndex({ age: 1 })
{
"ok" : 0,
"errmsg" : "ns not found",
"code" : 26,
"codeName" : "NamespaceNotFound"
} #信息错误,未找到.
=====正确====
> db.ccc.dropIndex({"name":-1})
{ "nIndexesWas" : 2, "ok" : 1 }
4)删除集合
#先确认自己在哪个库
> db
test2
#确认集合
> show tables;
inventory
test
#删除集合
> db.inventory.drop()
true
5)删除库
#先确认自己在哪个库
> db
test2
#删除库
> db.dropDatabase()
8. 排序/选取/跳过/分页
# 排序:sort
db.stu.find().sort({ age:1 }) 1正序 -1倒序
# 选取:limit
db.stu.find().limit(2) 选取两条数据
# 跳过:skip
db.stu.find().skip(2) 跳过前两条数据
选择中间两条 or 跳过前N条
db.stu.find().skip(0).limit(2).sort({ age:-1 })
优先级:先排序 - 跳过 - 选取
# 分页
var page = 1
var num = 2
var sk = (page-1) * num
db.stu.find().skip(sk).limit(num).sort({ age:-1 })
# 使用 sort() 方法对数据进行排序,sort() 方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列。
sort()方法基本语法如下所示:
> db.COLLECTION_NAME.find().sort({KEY:1})
把col集合中的数据按字段likes的降序排列:
>db.col.find({},{"title":1,_id:0}).sort({"likes":-1})
{ "title" : "PHP 教程" }
{ "title" : "Java 教程" }
{ "title" : "MongoDB 教程" }
9. 高级索引
考虑以下文档集合(users ):
文档包含了 address 子文档和 tags 数组。
{
"address": {
"city": "Los Angeles",
"state": "California",
"pincode": "123"
},
"tags": [
"music",
"cricket",
"blogs"
],
"name": "Tom Benzamin"
}
1)索引数组字段
假设我们基于标签来检索用户,为此我们需要对集合中的数组 tags 建立索引。
在数组中创建索引,需要对数组中的每个字段依次建立索引。所以在我们为数组 tags 创建索引时,会为 music、cricket、blogs三个值建立单独的索引。
使用以下命令创建数组索引:
>db.users.ensureIndex({"tags":1})
创建索引后,我们可以这样检索集合的 tags 字段:
>db.users.find({tags:"cricket"})
为了验证我们使用使用了索引,可以使用 explain 命令:
>db.users.find({tags:"cricket"}).explain()
以上命令执行结果中会显示 "cursor" : "BtreeCursor tags_1" ,则表示已经使用了索引。
2)索引子文档字段
假设我们需要通过city、state、pincode字段来检索文档,由于这些字段是子文档的字段,所以我们需要对子文档建立索引。
为子文档的三个字段创建索引,命令如下:
>db.users.ensureIndex({"address.city":1,"address.state":1,"address.pincode":1})
一旦创建索引,我们可以使用子文档的字段来检索数据:
>db.users.find({"address.city":"Los Angeles"})
查询表达不一定遵循指定的索引的顺序,mongodb 会自动优化。所以上面创建的索引将支持以下查询:
>db.users.find({"address.state":"California","address.city":"Los Angeles"})
同样支持以下查询:
>db.users.find({"address.city":"Los Angeles","address.state":"California","address.pincode":"123"})
10.导入数据
1) 导入.csv
// 格式:
mongoimport -h ip地址:端口号 -u 数据库用户名 -p 数据库密码 -d 数据库名称 -c 集合名称 --type csv --headerline --ignoreBlanks --file csv文件路径
// 实例:
mongoimport -d source_data -c corporation --type csv --headerline --file e:\Python_exercise\320.csv
// 说明:
-h:IP地址端口号(连接到远程数据库时需要使用,不填写则默认连接到本地test数据库)、用户名、密码可不填.
-c:如果未指定集合名称-c,mongoimport则从输入文件名中获取集合名称。如果输入文件具有扩展名,MongoDB将忽略集合名称中文件的扩展名
--type:指定要导入的文件类型。默认格式为json,但可以导入csv和tsv文件
headerline:如果使用headerline则使用第一行作为字段名称,否则,将第一行作为数据字段导入,仅仅用作csv或tsv文件导入,在导入json时用headerline则会报错
--ignoreBlanks:忽略csv和tsv导出中的空字段。如果未指定,则mongoimport在导入的文档中创建没有值的字段,ignoreBlanks仅适用于csv或tsv文件导入
统计表数量:
db.t1.count()
db.t1.count({"x":1})
'1. 注意,如果没有unique索引在mongodb中可以重复导入相同数据'
'2. 如果有唯一键限制的情况下.导入时会自动跳过重复条目.如下例图1'
2) 导入.json
mongodbimport --db 库名 -c 集合名 --type json C:\Users\zhang_zk\Desktop\new.json