前言
mongodb
是一个NoSQL
数据库, 可以分词查询, 可以基于地理位置查询, 记录以JSON
形式存储.
mongodb
的数据表又叫做数据集合, 关键字为collection
.
mongodb
是不存在join
这个概念的, 所以一切的关联查询都得通过外部程序来做.
安装配置(基于v3.4.18)
安装教程: Install MongoDB Community Edition on Red Hat Enterprise or CentOS Linux(国内可以用阿里云yum
镜像).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| yum install -y mongodb-org
mkdir -p /opt/mongodb/data/db /opt/mongodb/log cp /etc/mongod.conf /opt/mongodb/mongod.conf
sed -i 's#/var/log/mongodb/mongod.log#/opt/mongodb/log/mongod.log#g' /opt/mongodb/mongod.conf sed -i 's#/var/lib/mongo#/opt/mongodb/data/db#g' /opt/mongodb/mongod.conf sed -i 's#/var/run/mongodb/mongod.pid#/opt/mongodb/mongod.pid#g' /opt/mongodb/mongod.conf
mongod --version
mongod -f /opt/mongodb/mongod.conf
mongo 127.0.0.1:27071/test use admin db.shutdownServer()
|
用户权限
auth 用户名密码登录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| db.createUser({ user: "ahao", pwd: "ahao", customData: {msg:"我是一个新用户"}, roles:[{role:"dbOwner", db:"admin"}] }) 角色类型: read、readWrite、dbAdmin、dbOwner、userAdmin dbOwner = read + readWrite + dbAdmin
system: authorization: enabled
mongod -f /opt/mongodb/mongodb.conf mongo 127.0.0.1:12345 -u ahao -p ahao use admin db.system.users.find()
db.createRole({ _id: "唯一id", role: "角色名", db: "数据库名", privileges: [ { resource:{db:"数据库名", collection:"集合名", actions:[允许执行的操作]}} ] roles: [继承哪些角色] })
|
集群keyfile
keyfile文件认证
数据库
mongodb
数据库不用新建, 直接use
, 数据库会在插入记录的时候自动创建数据库及数据集合.
1 2 3 4 5 6 7 8 9 10 11 12 13
| use test_db db.test_collection.insert({x:1})
show dbs admin 0.000GB local 0.000GB test_db 0.000GB
use test_db db.dropDatabase()
|
表collection
同样, 数据表也是在插入时自动创建.
和关系型数据库不同, 不需要提前设置字段.
1 2 3 4 5 6 7 8 9 10 11
| use test_db
show collections db.test_collection.insert({x:1}) show collections test_collection
> db.test_collection.drop()
|
索引
在v3.0.0
后, 官方文档提到创建索引的函数createIndex()
替换掉了ensureIndex()
. 当然非要使用ensureIndex()
也是可以的.
创建索引的格式: db.集合名.createIndex({索引值}, {索引属性})
索引属性 |
语法 |
默认 |
名称 |
db.集合名.createIndex({索引值}, {name:"索引名称"}) |
字段名_1 或字段名_-1 |
唯一性 |
db.集合名.createIndex({索引值}, {unique:[true or false]}) |
false |
稀疏性 |
db.集合名.createIndex({索引值}, {sparse:[true or false]}) |
true , 避免为插入记录不存在的字段创建索引 |
是否定时删除 |
db.集合名.createIndex({索引值}, {expireAfterSeconds:秒数}) |
不删除 |
没有属性的普通索引
索引类型 |
说明 |
创建方法(1为正序, -1为逆序) |
_id 索引 |
自动创建的索引, 作为记录的唯一主键 |
db.test_collection.insert({name:1}) |
单键索引 |
为一个字段创建的索引, 字段值为单个元素 |
db.test_collection.createIndex({name:1}) |
多键索引 |
为一个字段创建的索引, 字段值为数组元素 |
db.test_collection.createIndex({class:1}) |
复合索引 |
为多个字段创建的索引 |
db.test_collection.createIndex({name:1, age:1}) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| use test_db
db.test_collection.getIndexes()
db.test_collection.insert({name:"Tom", age:12, friends:["Sum", "Kim"]})
db.test_collection.createIndex({name:1})
db.test_collection.createIndex({friends:1})
db.test_collection.createIndex({name:1, age:1})
db.test_collection.dropIndex("索引名")
|
过期索引TTL
一定时间后会过期的索引, 存储的值必须是时间类型, 如new Date()
. 如果是数组, 则取最小的时间.
一个字段不能同时有过期索引和复合索引.
当数据过期时, 对应的数据会自动删除. 但是mongodb
删除任务60
秒执行一次, 所以过期时间最好不要小于60
秒.
适用于登录信息、日志信息、缓存等不重要的信息.
创建语法: db.数据集合.createIndex({时间字段:1}, {expireAfterSeconds:秒数})
1 2 3 4 5 6 7 8 9
| use test_db db.login_info.insert({name:"Tom", login_time:new Date()})
db.login_info.createIndex({login_time:1}, {expireAfterSeconds:10})
db.login_info.find()
|
文本索引
说是文本索引, 其实就是对选择的字段进行分词索引. 所选的字段可以一个, 也可以多个.
一个数据集只有一个文本索引, 且只能是字符串类型的字段.
查询文本索引时, 不允许使用hint()
指定索引进行查询.
创建语法: db.数据集合.createIndex({字段:"text"})
1 2 3 4 5 6
| db.test_collection.createIndex({name:"text"})
db.test_collection.createIndex({name:"text", address:"text"})
db.test_collection.createIndex({"$**":"text"})
|
查询语法, 多个关键字用空格分隔, 默认为or
查询.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 语法 db.test_collection.find({ $text: { $search: 搜索字符串, $language: 指定语言(社区版不支持中文), $caseSensitive: 是否大小写敏感(默认false), $diacriticSensitive: 是否区别发音符号(默认false) } })
db.test_collection.find({$text:{$search:"hello world"}})
db.test_collection.find({$text:{$search:"\"hello world\""}})
db.test_collection.find({$text:{$search:"hello -world"}})
db.test_collection.find({$text:{$search:"\"ssl certificate\" authority key"}})
db.test_collection.find({$text:{$search:"hello"}}, {score:{$meta:"textScore"}}).sort({score:{$meta:"textScore"}})
|
2d地理位置索引(平面)
插入语法: db.数据集合.insert({字段名:[经度(-180,180), 纬度(-90,90)]})
创建语法: db.数据集合.createIndex({字段:"2d"},{min:最小值,max:最大值,bits:精度(默认26) })
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| db.test_location.find({loc:{$near:[10,20]}})
db.test_location.find({loc:{$near:[10,20]}}).limit(10)
db.test_location.find({loc:{$near:[10,20], $maxDistance:10}})
db.test_location.find({loc:{$geoWithin:{$box:[[1,2],[3,4]]}}})
db.test_location.find({loc:{$geoWithin:{$center:[[1,2], 3]}}})
db.test_location.find({loc:{$geoWithin:{$polygon:[[1,2], [1,10], [2,10], [1,5]]}}})
db.runCommand({ geoNear: 集合名, near: [x,y], minDistance: 最小距离(对2d索引无效, 对2dsphere索引有效), maxDistance: 最大距离 num: 数量 })
|
2dsphere地理位置索引(球面)
插入语法: db.数据集合.insert({字段名:{type:"Point",coordinates:[经度(-180,180), 纬度(-90,90)]}})
创建语法: db.数据集合.createIndex({字段:"2dsphere"})
点用GeoJSON
的形式表示, 参考GeoJSON Objects
1 2 3 4 5 6 7 8
| db.runCommand({ geoNear: 集合名, near: GeoJSON形式的值, minDistance: 最小距离(对2d索引无效, 对2dsphere索引有效), maxDistance: 最大距离 num: 数量 })
|
插入更新删除
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
> db.test_collection.insert({name:"小明", age: 10})
> for(i=1;i<3;i++) db.test_collection.insert({name:"name"+i, age:i})
> db.test_collection.update({name:"小明"}, {name:"新名字"})
> db.test_collection.update({name:"小明"}, {$set{name:"新名字"}})
> db.test_collection.update({name:"小红"}, {name:"新小红", age: 11}, true)
> db.test_collection.update({age:10}, {$set{age: 21}}, false, true)
> db.test_collection.remove({age:21})
|
查询
1 2 3 4 5 6 7 8 9 10 11 12
| db.test_collection.find()
db.test_collection.find().count()
db.test_collection.find().skip(3).limit(4).sort({name: -1})
db.test_collection.findOne({name:"小明"})
> db.test_collection.find({x:{$exists:true}})
> db.test_collection.find().sort({$natural:-1}).limit(10)
|