MongoDB入门

MongoDB数据库


一、MongoDB介绍
1、简介

MongoDB(Mongo巨大,庞大)是最像关系型数据的nosql数据库,除以非关系数据库和关系型数据之间,MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。用于大规模数据的存储,数据库革命性运动,支持的数据格式json/bson(存放文档)。


2、Nosql四大家族
  • 键值存储数据库

  • 文档存储数据库

  • 列存储数据库

  • 图形存储数据库


3、Nosql的优点
  • 高可扩展性
  • 没有标准化
  • 分布式计算
  • 有限的查询功能
  • 低成本

4、Nosql的缺点
  • 最终一直是不直观的

  • 架构的灵活性半结构化数据

  • 没有复杂关系


5、Nosql适用几种情况
  • 数据模型比较简单
  • 需要灵活性更强的 IT 系统
  • 对数据库性能要求较高
  • 不需要高度的数据一致性
  • 对于给定的 Key,比较容易映射复杂值的环境

二、Linux安装MongoDB
1、安装流程
# 上传资源到指定路径
cd /usr/local
# 解压文件并重命名
tar -zxvf ./mongodb-xxx.xxx
mv ./mongodb-xxx.xx ./mongodb
# 创建存放数据的目录
mkdir -p /usr/local/mongodb/data/db
# 创建存放日志的目录
mkdir -p /usr/local/mongodb/logs
# 创建日志记录文件
touch /usr/local/mongodb/logs/mongodb.log

在 bin 目录下增加一个 mongodb.conf配置文件

# 数据文件存放目录
dbpath = /usr/local/mongodb/data/db
# 日志文件存放目录
logpath = /usr/local/mongodb/logs/mongodb.log
# 以追加的方式记录日志
logappend = true
# 端口默认为 27017
port = 27017
# 对访问 IP 地址不做限制,默认为本机地址
bind_ip = 0.0.0.0
# 以守护进程的方式启用,即在后台运行
fork = true

启动mongodb

# 指定配置文件的方式启动服务
bin/mongod -f bin/mongodb.conf

为方便启动客户端配置环境变量

# 修改etc/profile文件
# 将mongodb的环境配置添加进取
export NODE_HOME=/usr/local/nodejs/node-v12.13.1-linux-x64
export MONGODB_HOME=/usr/local/mongodb
export JAVA_HOME=/usr/java/jdk-11.0.12
export PATH=$JAVA_HOME/bin:$PATH:$NODE_HOME/bin:$PATH:$MONGODB_HOME/bin
# 刷新后便可在任何地方启动
source /etc/profile

在这里插入图片描述


常用命令

db.version()查看版本号
show dbs 查看数据库
show users 查看用户信息
--shutdown 关闭mongoDB 
use admin 切换数据库
db.shutdownServer() 关闭服务
db.c1.drop() 删除集合
db.createCollection() 创建集合

2、用户权限管理

常用权限:
在这里插入图片描述


#use 切换数据库,无则创建新的
use admin
# 查看用户
db.system.users.find()
# 创建用户
db.createUser({user:"uaad",pwd:"uaad",roles:[{role:"userAdminAnyDatabase",db:"admin"}]})
# 重启服务,退出修改配置
db.shutdownServer()

MongoDB.conf配置文件

# 添加一句,启动身份验证 
auth = true

再次启动客户端需要认证db.system.users.find()
在这里插入图片描述

# 认证
db.auth("uaad","uaad")
# 更新用户权限
db.updateUser("uaad", {"roles":[{"role":"userAdminAnyDatabase",db:"admin"},{role:"readWriteAnyDatabase",db:"admin"},{role:"dbAdminAnyDatabase",db:"admin"}]})
# 密码更新
- 使用 `db.updateUser("用户名", {"pwd":"新密码"})` 函数更新密码
- 使用 `db.changeUserPassword("用户名", "新密码")` 函数更新密码
# 删除用户
db.dropUser()
# 进入数据库删除数据库
db.dropDatabase()

在这里插入图片描述

windows客户端可以安装Robo 3T 或者Navicat等


三、MongoDB基本操作
1、基本操作
# 创建获取切换数据库
use mydb
# 当前数据库
db
# 插入数据到文档
db.table1.insert({"name":"zhangsan"})
# 删除数据库
db.dropDatabase()
# 创建集合(类似表)
db.createCollection(name, options)
#插入单条文档
- db.c1.insert({"name":"a"})
- db.c1.insertOne({"name":"a"})
- db.c1.save({"name":"a"})
user1 = {
    "name":"zhangsan",
    "age":18,
    "hobbies":["music", "read"],
    "addr":{
        "country":"China",
        "city":"BJ"
    }
}

db.user.insert(user1)
db.user.insertOne(user2)
db.user.save(user3)
# 多条插入
db.user.insert([user1, user2, user3, user4, user5])
- `db.c1.insert([{name:"a"}, {name:"b"}])`
- `db.c1.insertMany([{name:"a"}, {name:"b"}])`
- `db.c1.save([{name:"a"}, {name:"b"}])`

# 更新文档
user = {
    "name":"wangwu",
    "age":20,
    "hobbies":["music", "read"],
    "addr":{
        "country":"China",
        "city":"BJ"
    }
}

# 修改单条
db.user.updateOne({"name":"lisi"}, {"$set": user}) 
# 查找到的匹配数据如果是多条,只会修改第一条
db.user.update({"name":"lisi"}, user) # 修改单条等价于 updateOne()
# 查找到的匹配数据如果是多条,修改所有匹配到的记录
db.user.update({"name":"lisi"}, {"$set": user}, false, true) # 修改多条
db.user.updateMany({"name":"张三123123"}, {"$set": user}) # 修改多条
# 注意:更新文档是更新整个文档的操作,如果修改的值只有 name 和 age,除了 _id 以外其他属性将会被删除。

更新常用操作符
在这里插入图片描述


查询、删除文档

# 删除
#删除符合条件的第一个文档
db.user.deleteOne(<query>)
#删除所有数据命令
db.user.remove({})
#清空该集合() 等价于上一条
db.user.deleteMany({})
# 查询
# 等同于db.user.find({})
db.user.find()
# 去重
db.user.distinct('name')
# pretty() 方法以格式化的方式来显示所有文档
db.user.find().pretty()

# 比较运算符
#1、select * from user where id = 3
db.user.find({"_id":3})

#2、select * from user where id != 3
db.user.find({"_id":{"$ne":3}})

#3、select * from user where id > 3
db.user.find({"_id":{"$gt":3}})

#4、select * from user where age < 3
db.user.find({"age":{"$lt":3}})

#5、select * from user where id >= 3
db.user.find({"_id":{"$gte":3}})

#6、select * from user where id <= 3
db.user.find({"_id":{"$lte":3}})

正则,投影,数据组,排序,分页,统计,聚合等操作略


2、索引

创建索引

# 格式
db.COLLECTION_NAME.ensureIndex({KEY:1})
# key`:创建的索引字段,1为指定按升序创建索引,-1则为按降序来创建索引
db.user.ensureIndex({"name":-1})
# 指定所建立索引的名字
db.user.ensureIndex({"name":1},{"name":"nameIndex"})

查询索引

db.COLLECTION_NAME.getIndexes()

删除索引

# 格式
db.COLLECTION_NAME.dropIndex(INDEX_NAME)

四、Java集成MongoDB

创建一个maven工程,java项目即可,引入依赖编写测试类进行测试。

1、引入依赖
  <!-- mongodb java依赖 -->
    <dependency>
      <groupId>org.mongodb</groupId>
      <artifactId>mongo-java-driver</artifactId>
      <version>3.12.7</version>
    </dependency>
2、编写测试类
public class AppTest 
{
    /**
     * Rigorous Test :-)
     */
    @Test
    public void shouldAnswerWithTrue() {
        /**
         * 连接mongodb服务器
         * mongodb://user1:pwd1@host1/?authSource=db1
         * username:用户名
         * password:密码
         * host1:服务器
         * authSource:认证数据库
         */
        MongoClient mongoClient = MongoClients.create("mongodb://uaad:uaad@192.168.168.129/?authSource=admin");
        //获取数据库
        MongoDatabase database = mongoClient.getDatabase("test001");
        //获取集合
        MongoCollection<Document> collection = database.getCollection("user");
        //获取数据
        System.out.println("collection.find().first().toJson() = " + collection.find().first().toJson());
        System.out.println("connect to database successful");
        //关闭客户端
        if (mongoClient != null) {
            mongoClient.close();
        }
    }

    /**
     * 操作集合
     */
    @Test
    public void testCollection() {
        MongoClient mongoClient = MongoClients.create("mongodb://uaad:uaad@192.168.168.129/?authSource=admin");
        //获取数据库
        MongoDatabase database = mongoClient.getDatabase("test001");
        //获取集合,如果集合不存在,会在第一次为该集合创建数据时创建集合
        MongoCollection<Document> emp = database.getCollection("emp");
        //获取集合命名空间,格式数据库.集合
        System.out.println(emp.getNamespace());

        //创建固定大小的集合,大小1MB
        database.createCollection("cappedCollection",
                new CreateCollectionOptions().capped(true).sizeInBytes(0x100000));

        /**
         * 创建带校验规则的集合
         * 在更新和插入期间验证文档的功能
         * 验证规则是使用ValidationOptions在每个集合的基础上指定的,它接受指定验证规则或表达式的筛选器文档。
         * 文档插入数据时必须存在emali字段或者phone字段
         */
        ValidationOptions collOptions = new ValidationOptions().validator(
                Filters.or(Filters.exists("email"), Filters.exists("phone")));
        database.createCollection("contacts",
                new CreateCollectionOptions().validationOptions(collOptions));
    }

    /**
     * 操作集合
     */
    @Test
    public void testDocuments() {
        MongoClient mongoClient = MongoClients.create("mongodb://uaad:uaad@192.168.168.129/?authSource=admin");
        //获取数据库
        MongoDatabase database = mongoClient.getDatabase("test001");
        MongoCollection<Document> collection = database.getCollection("test");
        //创建一个文档,参数可以接收键值对,也可以直接接收一个Map对象
        //文档对象的本质是BSON类型,该类型对应java.util.Map;BSON数组对应的是java.util.List
        Document doc = new Document("name", "MongoDB")
                .append("type", "database")
                .append("count", 1)
                .append("versions", Arrays.asList("v3.2", "v3.0", "v2.6"))
                .append("info", new Document("x", 203).append("y", 102));
        //插入一个文档,如果文档没有指定_id,则自动生成_id和值
        collection.insertOne(doc);

        // 批量插入
        List<Document> documents = IntStream.range(0, 100).mapToObj(i -> new Document("i", i)).collect(Collectors.toList());
        collection.insertMany(documents);

        // 查询集合大小
        System.out.println(collection.countDocuments());

        // 更新一个文档,参数1:条件,参数2:要更新的内容,其中$set代表只更新部分字段
        collection.updateOne(eq("i", 10), new Document("$set", new Document("i", 150)));

        // 更新多个文档,对于i小于100的所有文档,将i的值增加100
        UpdateResult updateResult = collection.updateMany(lt("i", 100), inc("i", 100));
        System.out.println(updateResult.getModifiedCount());

        //删除一个文档
        // collection.deleteOne(eq("i", 110));

        //删除多个文档,删除i大于等于100的文档
//        DeleteResult deleteResult = collection.deleteMany(gte("i", 100));
//        System.out.println(deleteResult.getDeletedCount());
    }



    /**
     * 查询
     */
    @Test
    public void testQuery() {
        MongoClient mongoClient = MongoClients.create("mongodb://uaad:uaad@192.168.168.129/?authSource=admin");
        //获取数据库
        MongoDatabase database = mongoClient.getDatabase("test001");
        MongoCollection<Document> collection = database.getCollection("emp");
        //查询所有文档, 如果需要限制返回行数,可以在find()方法后添加first()、limit()等方法
        MongoCursor<Document> cursor = collection.find().iterator();
        try {
            while (cursor.hasNext()) {
                System.out.println(cursor.next().toJson());
            }
        } finally {
            cursor.close();
        }
        //查询所有文档,不推荐,有游标泄露风险
        for (Document document : collection.find()) {
            System.out.println(document.toJson());
        }

        /**
         * 条件查询,主要依靠Filter类
         * 条件:
         *  stars>=2,stars<5
         *  categories字段等于“Bakery”(如果categories是数组,则包含字符串“Bakery”作为元素)
         */
//        FindIterable<Document> documents = collection.find(
//                new Document("stars", new Document("$gte", 2)
//                        .append("$lt", 5))
//                        .append("categories", "Bakery"));


        //等价于上一个条件查询
        FindIterable<Document> documents = collection.find(and(gte("stars", 2), lt("stars", 5), eq("categories",
                "Bakery")));


        /**
         * 投影
         * 展示:name,stars,categories
         */
        FindIterable<Document> documents = collection.find(and(gte("stars", 2), lt("stars", 5), eq("categories",
                        "Bakery")))
                .projection(new Document("name", 1)
                        .append("stars", 1)
                        .append("categories", 1)
                        .append("_id", 0));


         等价于上一个投影
        FindIterable<Document> documents = collection.find(and(gte("stars", 2), lt("stars", 5), eq("categories",
                        "Bakery")))
                .projection(fields(include("name", "stars", "categories"), excludeId()));

        /**
         * 排序:
         *  ascending:正序
         *  descending:倒序
         */
        FindIterable<Document> documents = collection
                .find(and(gte("stars", 2), lt("stars", 5), eq("categories", "Bakery")))
                .sort(Sorts.ascending("name"));


        /**
         * 聚合
         *  匹配categories为Bakery字段
         *  对stars分组并且计数
         */
        AggregateIterable<Document> documents = collection.aggregate(
                Arrays.asList(
                        Aggregates.match(eq("categories", "Bakery")),
                        Aggregates.group("$stars", Accumulators.sum("count", 1))
                ));

        /**
         * 复杂聚合
         *  展示name和firstCategory
         *  firstCategory为categories索引下标0的值,也就是categories中第一个值
         */
        AggregateIterable<Document> documents = collection.aggregate(
                Arrays.asList(
                        Aggregates.project(
                                fields(
                                        excludeId(),
                                        include("name"),
                                        Projections.computed(
                                                "firstCategory",
                                                new Document("$arrayElemAt", Arrays.asList("$categories", 0))
                                        )
                                )
                        )
                )
        );

        for (Document document : documents) {
            System.out.println(document.toJson());
        }

    }
}

排序查询结果:
在这里插入图片描述


未完待续........

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

每日小新

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值