MongoDB
简介
以json为数据模型的文档型数据库
应用型数据库存储海量数据
动态建模,没有特定字段格式
支持副本机制,分片机制,为分布式而生
安装
win
Windows下载
设置数据库文件存储路径和日志存储路径
不要安装MongoDB-Compass(图形化界面)
配置环境变量(安装目录下bin目录)
为MongoDB添加一个数据库文件夹db,新建一个文件夹安装路径\data\db,这个文件夹会储存数据库的数据linux
tar -zxvf mongodb-4.4.2.tgz // 添加到系统执行路径 export PATH=$PATH:/usr/local/mongodb/mongodb-linux-x86_64-rhel70-4.4.22/bin source ~/.bashrc // 创建数据目录,日志目录 mkdir -p /data/db/logpath // 创建日志输出 cd /data/db/logpath touch output.out // 后台启动,需要指定--logpath mongod --logpath /data/db/logpath/output.out --fork // 本机客户端连接 mongo (其它机器:mongo --host 121212 --port 2121) // 设置密码 use admin db.createUser({user:"root",pwd:"root",roles:[{role:"root",db:"admin"}]}) show users // 关闭服务 mongod --shutdown --dbpath /data/db // 授权启动 mongod --logpath /data/db/logpath/output.out --fork --auth // 开启远程连接参数 --bind_ip_all mongod --logpath /data/db/logpath/output.out --fork --auth --bind_ip_all // 连接 mongo -u root
MongoDB 后台管理 Shell
执行安装目录下bin目录下mongo.exe文件,MongoDB Shell是MongoDB自带的交互式Javascript shell,用来对MongoDB进行操作和管理的交互式环境。
相关命令
db: # 查看当前操作数据库
show databases
use demo # 使用/创建
db.users.insertOne({"name":"zhangsan",age:18}) # 插入数据到集合users
db.users.find() # 查看
# id是客户端生成的
ObjectId("64704ebce4ed76702416307f").getTimestamp()
db.dropDatabase() #删除数据库,先切换到指定数据库
db.collection.drop() #删除集合
db.users.insertMany([{doc}, {doc}],
{
writeConcern: doc,
ordered: true/false #有序(一旦失败,后面的也不插入了),无序
})
majority:写操作需要被复制到多大节点数才成功
# 精准查询
db.users.find({name: "test"})
db.users.find({name: "test", age: 11})
db.users.find({name: "test"}, {_id:0, age:1}) # 只返回age字段
db.users.find({$and:[{name: "test"}, {age: 11}]})
db.users.find({$or:[{name: "test"}, {age: 11}]})
db.users.find({age:{$gt:11}})
$ne不等于 $gte大于等于 $lt小于 $lte小于等于
db.users.find({age:{$in:[11,12]}})
$in $nin
db.users.count()
db.users.find().skip(1).limit(2)
db.users.find().sort({age: 1}) # -1逆序
db.movies.insertMany([{name:"test", tag:["动作","热血"]}])
db.movies.find({}, {tag:{$slice:1}}) #slice
db.users.updateOne({name:"test"}, {$set:{flag: 1}}) #有这个字段就修改,没有就追加,One只会改一个匹配值
db.users.updateMany({name:"test"}, {$unset:{flag: 1}}) #删除字段
db.createCollection(name, options)
options: (capped 布尔 是否创建固定大小集合 | size 数值 最大大小,字节 | max 数值 文档的最大数量)
# 创建固定集合 mycol,整个集合空间大小 6142800 B, 文档最大个数为 10000 个。
db.createCollection("mycol", { capped : true, autoIndexId : true, size : 6142800, max : 10000 } )
db.col.save(document) # 不指定 _id 字段 save() 方法类似于 insert() 方法。如果指定 _id 字段,则会更新该 _id 的数据
# 更新
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
}
)
query : update的查询条件,类似sql update查询内where后面的。
update : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的
upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
writeConcern :可选,抛出异常的级别。
# 更新标题(title),如果修改多条相同的文档需要设置 multi 参数为 true
db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}})
# 删除文档(前面是条件,true代表只删除一条默认为false,全删除)
db.col.remove({'title':'MongoDB 教程'}, true)
# 删除所有
db.col.remove({})
db.col.find().pretty() # 以格式化的方式来显示所有文档
# 条件语句查询
db.col.find({"by":"test"}).pretty() # where by = 'test'
db.col.find({"likes":{$lt:50}}).pretty() # where likes < 50
db.col.find({"likes":{$lte:50}}).pretty() # where like <= 50
db.col.find({"likes":{$gt:50}}).pretty() # where likes > 50
db.col.find({"likes":{$ne:50}}).pretty() # where likes != 50
# AND,OR联合
db.col.find({"likes": {$gt:50}, $or: [{"by": "教程"},{"title": "MongoDB"}]}).pretty()
# 获取 "col" 集合中 title 为 String 的数据
db.col.find({"title" : {$type : 'string'}})
db.col.createIndex({"title":1,"description":-1}) # 建立索引,1升序,-1降序,这是复合索引
# 使用aggregate()计算 类似:select by_user, count(*) from mycol group by by_user
db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])
权限
添加用户
创建一个用户名root,密码root的管理员
use admin
db.createUser({user:"root",pwd:"root",roles:[{role:"root",db:"admin"}]})
超级用户一定是属于admin数据库的
开启远程链接
修改mongodb.cfg
# network interfaces
net:
port: 27017
bindIp: 127.0.0.1,0.0.0.0
开启密码登录
修改mongodb.cfg
# network interfaces
security:
authorization: enabled
主从
复制集:实现服务高可用,类似Redis哨兵,复制集最多50节点,投票最多7
数据写入主节点时将数据复制到副本
主节点发生故障自动选举一个新的主节点
搭建
cd /data/
mkdir db1 mkdir db2 mkdir db3
// 创建日志文件
touch db1/mongod.log touch db2/mongod.log touch db3/mongod.log
// 创建配置文件
touch db1/mongod.conf touch db1/mongod.conf touch db1/mongod.conf
// conf内容(配置三个,改path,dbpath,port)
systemLog:
destination: file
path: /data/db1/mongod.log
logAppend: true
storage:
dbPath: /data/db1
net:
bindIp: 0.0.0.0
port: 28017
replication:
replSetName: rs0
processManagement:
fork: true
- 启动
mongod -f /data/db1/mongod.conf mongod -f /data/db2/mongod.conf mongod -f /data/db3/mongod.conf // 连接任一复制集 mongo --port 28017 // 配置 var config={_id:"rs0",members:[{_id:0,host:"localhost:28017"},{_id:1,host:"localhost:28018"},{_id:2,host:"localhost:28019"}]} rs.initiate(config)
- 从节点读
只有主节点能写默认从节点不能读,需在从节点配置 rs.secondaryOk()
分片集群
将数据水平拆分到不同服务器,并发量突破单机性能瓶颈
路由节点,数据节点,配置节点
路由节点:提供集群单一入口,转发应用端请求,选择合适数据节点进行读写
配置节点:存储集群相关信息
数据节点:以复制集为单位,横向扩展,分片之间数据不重复,所有数据在一起才可以完整工作
Java连接
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<version>4.1.1</version>
</dependency>
public static void main(String[] args) {
MongoClient mongoClient = MongoClients.create("mongodb://192.168.31.8:28017");
// 获取数据库
MongoDatabase mongoDatabase = mongoClient.getDatabase("zwq");
// 获取集合
MongoCollection<Document> users = mongoDatabase.getCollection("users");
Document doc = new Document("name", "bob").append("age", 22);
users.insertOne(doc);
Bson eq = eq("name", "bob");
FindIterable<Document> find = users.find(eq);
Document findUser = find.first();
System.out.println(findUser);
}
springboot
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<optional>true</optional>
</dependency>
spring:
data:
mongodb:
# 集群配置mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
# uri: mongodb://192.168.204.81:27017,192.168.204.82:27017,192.168.204.83:27017/testdb?maxPoolSize=512
uri: mongodb://192.168.31.8:28017/zwq?maxPoolSize=512
# authentication-database: admin # 登录认证的逻辑库名
# username: admin #用户名
# password: abc123456 #密码
- 实体
@Data @Document(collection = "users") public class User { @Id private String id; private String name; private Integer age; }
- service
public interface UserService extends MongoRepository<User, String> { }
- controller
@RestController public class UserController { @Autowired UserService userService; @RequestMapping("/users") public void users() { List<User> list = userService.findAll(); list.stream().forEach((item) -> { System.out.println(item.toString()); }); } }