MongoDB


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());
            });
        }
    
    }

  目录