MongoDB入门到使用

得意时要看淡,失意时要看开。不论得意失意,切莫大意;不论成功失败,切莫止步。志得意满时,需要的是淡然,给自己留一条退路;失意落魄时,需要的是泰然,给自己觅一条出路MongoDB入门到使用,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

MongoDB⽂档地址: https://docs.mongodb.com/manual/

📖简介

MongoDB是⼀个 基于分布式⽂件存储的数据库 。由C++语⾔编写。旨在 为WEB 应⽤提供可扩展⾼性能数据存储解决⽅案 。 MongoDB是⼀个 介于关系数据库和⾮关系数据库 之间的产品,是⾮关系数据 库当中功能最丰富,最像关系数据库的。他⽀持的数据结构⾮常松散,是 类似json的bson格式,因此可以存储⽐较复杂的数据类型 。Mongo最⼤的 特点是他⽀持的查询语⾔⾮常强⼤,其语法有点类似于⾯向对象的查询语 ⾔, ⼏乎可以实现类似关系数据库单表查询的绝⼤部分功能,⽽且还⽀持对数据 建⽴索引。

特点

  • ⾯向集合存储,易存储对象类型的数据

  • ⽀持查询,以及动态查询

  • ⽀持RUBY,PYTHON,JAVA,C++,PHP,C#等多种语⾔

  • ⽂件存储格式为BSON(⼀种JSON的扩展)

  • ⽀持复制和故障恢复和分⽚

  • ⽀持事务⽀持

  • 索引 聚合 关联….

应⽤场景

  • 游戏应⽤:使⽤云数据库MongoDB作为游戏服务器的数据库存储⽤户信 息。⽤户的游戏装备、积分等直接以内嵌⽂档的形式存储,⽅便进⾏查 询与更新。

  • 物流应⽤:使⽤云数据库MongoDB存储订单信息,订单状态在运送过程 中会不断更新,以云数据库MongoDB内嵌数组的形式来存储,⼀次查询 就能将订单所有的变更读取出来,⽅便快捷且⼀⽬了然。

  • 社交应⽤:使⽤云数据库MongoDB存储⽤户信息以及⽤户发表的朋友圈 信息,通过地理位置索引实现附近的⼈、地点等功能。并且,云数据库 MongoDB⾮常适合⽤来存储聊天记录,因为它提供了⾮常丰富的查询, 并在写⼊和读取⽅⾯都相对较快。

  • 视频直播:使⽤云数据库MongoDB存储⽤户信息、礼物信息等。

  • ⼤数据应⽤:使⽤云数据库MongoDB作为⼤数据的云存储系统,随时进 ⾏数据提取分析,掌握⾏业动态。

🔨安装

Docker⽅式安装

  1. 拉取 mongodb mongodb 镜像

docker pull mongo:5.0.5
MongoDB入门到使用

  1. 运行mongo镜像

docker run -d --name mongo -p 27017:27017 mongo:5.0.5
MongoDB入门到使用

  1. 进⼊ mongo 容器

docker exec -it eebed9d883f0 bash
MongoDB入门到使用

📌核心概念

mongodb中的库就类似于传统关系型数据库中库的概念,⽤来通过不同库隔离不 同应⽤数据 。mongodb中可以建⽴多个数据库。每⼀个库都有⾃⼰的集合 和权限,不同的数据库也放置在不同的⽂件中。默认的数据库为”test”,数 据库存储在启动指定的data⽬录中。

集合

集合就是 MongoDB ⽂档组,类似于 RDBMS (关系数据库管理系统: Relational Database Management System)中的表的概念。 集合存在于数据库中,⼀个库中可以创建多个集合。每个集合没有固定的 结构,这意味着你在对集合可以插⼊不同格式和类型的数据,但通常情况 下我们插⼊集合的数据都会有⼀定的关联性。

文档

文档集合中⼀条条记录,是⼀组键值(key-value)对(即 BSON)。MongoDB 的 ⽂档不需要设置相同的字段,并且相同的字段不需要相同的数据类型,这 与关系型数据库有很⼤的区别,也是 MongoDB ⾮常突出的特点。

⼀个简单的⽂档例⼦如下:

{"site":"www.baidu.com", "name":"百度"}

关系总结

RDBMS

MongoDB

数据库

数据库

集合

文档

字段

📝基本操作

  • 查看所有库

 show databases; | show dbs;
MongoDB入门到使用

注意:

  • admin : 从权限的⻆度来看,这是”root”数据库。要是将⼀个⽤户添加到这个数据库,这个⽤户⾃动 继承所有数据库的权限。⼀些特定的服务器端命令也只能从这个数据库运⾏,⽐如列出所有的数据库 或者关闭服务器。

  • local : 这个数据永远不会被复制,可以⽤来存储限于本地单台服务器的任意集合

  • config : 当Mongo⽤于分⽚设置时,config数据库在内部使⽤,⽤于保存分⽚的相关信息。

  • 创建数据库

 use 库名
MongoDB入门到使用

注意: use 代表创建并使⽤,当库中没有数据时默认不显示这个库

  • 删除数据库

db.dropDatabase()

MongoDB入门到使用

默认删除当前选中的库

  • 查看当前所在库

db;
MongoDB入门到使用

集合

  • 查看库中所有集合

show collections; | show tables;
MongoDB入门到使用

  • 创建集合

db.createCollection('集合名称', [options])
MongoDB入门到使用

options可以是如下参数

字段

类 型

描述

capped

布尔

(可选)如果为 true,则创建固定集合。固定集合是指有着固定⼤⼩的集合,当达到最 ⼤值时,它会⾃动覆盖最早的⽂档。 当该值为 true 时,必须指定 size 参数

size

数值

(可选)为固定集合指定⼀个最⼤值,即字节数。 如果capped 为 true,也需要指定该 字段 。

max

数值

(可选)指定固定集合中包含⽂档的最⼤数量。

注意:当集合不存在时,向集合中插⼊⽂档也会⾃动创建该集合。

  • 删除集合

db.集合名称.drop();
MongoDB入门到使用

⽂档

参考⽂档: https://docs.mongodb.com/manual/reference/method/

  • 插⼊⽂档

  1. 单条⽂档

db.集合名称.insert({"name":"小芳","age":23,"bir":"2023-1-1"});
  1. 多条⽂档

db.集合名称.insertMany(
 [ <document 1> , <document 2>, ... ],
 {
 writeConcern: 1,//写⼊策略,默认为 1,即要求确认写操作,0 是不要求。
 ordered: true //指定是否按顺序写⼊,默认 true,按顺序写⼊。
 }
)

db.集合名称.insert([
 {"name":"aa","age":23,"bir":"2022-12-12"},
 {"name":"bb","age":25,"bir":"2022-12-12"}
]);
MongoDB入门到使用

  1. 脚本⽅式

for(let i=0;i<100;i++){
 db.users.insert({"_id":i,"name":"mongo_"+i,"age":23});
}
MongoDB入门到使用

注意:在 mongodb 中每个⽂档都会有⼀个_id作为唯⼀标识,_id默认会⾃动⽣成如果⼿动指定将使⽤⼿动指定 的值作为_id 的值。

  • 查询所有

db.集合名称.find();
MongoDB入门到使用

  • 删除⽂档

db.集合名称.remove(
 <query>,
 {
     justOne: <boolean>,
     writeConcern: <document>
 }
)
MongoDB入门到使用

  • 参数说明: query : 可选 删除的⽂档的条件。 justOne : 可选 如果设为 true 或 1,则只删除⼀个⽂档,如果不设置该参数,或使⽤默认值 false,则删 除所有匹配条件的⽂档。 writeConcern : 可选 抛出异常的级别。

  • 更新⽂档

db.集合名称.update(
 <query>,
 <update>,
 {
 upsert: <boolean>,
 multi: <boolean>,
 writeConcern: <document>
 }
);
MongoDB入门到使用

使用$set

MongoDB入门到使用

参数说明:

  • query : update的查询条件,类似sql update查询内where后⾯的。

  • update : update的对象和⼀些更新的操作符(如$,$inc…)等,也可以理解为sql update查询内set后⾯的

  • upsert : 可选 ,这个参数的意思是,如果不存在update的记录,是否插⼊objNew,true为插⼊,默认是 false,不插⼊。

  • multi : 可选 ,mongodb 默认是false,只更新找到的第⼀条记录,如果这个参数为true,就把按条件查出来 多条记录全部更新。

  • writeConcern : 可选 ,抛出异常的级别。

- db.集合名称.update({"name":"zhangsan"},{name:"11",bir:new date()})
 `这个更新是将符合条件的全部更新成后⾯的⽂档,相当于先删除在更新`

- db.集合名称.update({"name":"xiaohei"},{$set:{name:"mingming"}})
 `保留原来数据更新,但是只更新符合条件的第⼀条数据`

- db.集合名称.update({name:”⼩⿊”},{$set:{name:”⼩明”}},{multi:true}) 
 `保留原来数据更新,更新符合条件的所有数据`

- db.集合名称.update({name:”⼩⿊”},{$set:{name:”⼩明”}},{multi:true,upsert:true})
 `保留原来数据更新,更新符合条件的所有数据 没有条件符合时插⼊数据

🔍⽂档查询

MongoDB 查询⽂档使⽤ find() ⽅法。find() ⽅法以⾮结构化的⽅式来显示所有⽂档。

语法

 db.集合名称.find(query, projection)
  • query :可选,使⽤查询操作符指定查询条件

  • projection :可选,使⽤投影操作符指定返回的键。查询时返回⽂档中所有键值, 只需省略该参数即可 (默认省略)。 (类似于mysql中 select keys…)

如果需要以易读的⽅式来读取数据,可以使⽤ pretty() ⽅法,语法格式如下:

db.集合名称.find().pretty()

注意: pretty() ⽅法以格式化的⽅式来显示所有⽂档。

对⽐语法

如果你熟悉常规的 SQL 数据,通过下表可以更好的理解 MongoDB 的条件语句查询:

MongoDB入门到使用

AND

db.集合名称.find({key1:value1, key2:value2,...}).pretty()

类似于 WHERE 语句:WHERE key1=value1 AND key2=value2

OR

MongoDB OR 条件语句使⽤了关键字 $or,语法格式如下:

> db.集合名称.find(
     {
         $or: [
             {key1: value1}, {key2:value2}
         ]
     }
).pretty()

类似于 WHERE 语句:WHERE key1=value1 or key2=value2

AND 和 OR 联合

 db.集合名称.find({"age": {$gt:50}, $or: [{"name": "张三"},{"name":
"MongoDB"}]}).pretty();

类似SQL语句为:’where age >50 AND (name = ‘张三’ OR name = ‘MongoDB’)’

数组中查询

-- 测试数据
> db.集合名称.insert({ "_id" : 11, "age" : 29, "likes" : [ "看电视", "读书xx", "游戏" ], "name"
: "xx" })

-- 执⾏数组查询
> db.users.find({likes:"看电视"})

-- $size 按照数组⻓度查询
> db.users.find({likes:{$size:3}});

模糊查询

类似 SQL 中为 ‘where name like ‘%name%”

db.users.find({likes:/火/});

注意:在 mongoDB 中使⽤正则表达式可以是实现近似模糊查询功能

排序

> db.集合名称.find().sort({name:1,age:1}),
- 1 升序 -1 降序

类似 SQL 语句为: ‘order by name,age’

分⻚

db.集合名称.find().sort({条件}).skip(start).limit(rows);

类似于 SQL 语句为: ‘limit start,rows’

总条数

> db.集合名称.count();
> db.集合名称.find({"name":"火山"}).count();

类似于 SQL 语句为: ‘select count(id) from ….’

去重

db.集合名称.distinct('字段')

指定返回字段

db.集合名称.find({条件},{name:1,age:1})
- 参数2: 1 返回 0 不返回 `注意:1和0不能同时使⽤`

🔖$type

说明

$type操作符是基于BSON类型来检索集合中匹配的数据类型,并返回结果。 MongoDB 中可以使⽤的类型如下表所示:

MongoDB入门到使用

使用

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

db.col.insert({title: 'MongoDB 教程', 
    description: 1234,
    by: '火山',
    url: 'http://www.runoob.com',
    tags: ['mongodb'],
    likes: 100
})

如果想获取 “col” 集合中 description 为 String 的数据,可以使⽤以下命令:

db.col.find({"description" : {$type : 2}}).pretty();
或
db.col.find({"description" : {$type : 'string'}}).pretty();

如果想获取 “col” 集合中 tags 为 Array 的数据,可以使⽤以下命令:

db.col.find({"tags" : {$type : 'array'}}).pretty();

📒索引

https://www.mongodb.com/docs/manual/indexes/

索引通常能够极⼤的提⾼查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个⽂件并 选取那些符合查询条件的记录。这种扫描全集合的查询效率是⾮常低的,特别在处理⼤量的数据时,查询可 以要花费⼏⼗秒甚⾄⼏分钟,这对⽹站的性能是⾮常致命的。索引是特殊的数据结构,索引存储在⼀个易于 遍历读取的数据集合中,索引是对数据库表中⼀列或多列的值进⾏排序的⼀种结构。

原理

MongoDB入门到使用

从根本上说,MongoDB中的索引与其他数据库系统中的索引类似。MongoDB在集合层⾯上定义了索引,并⽀ 持对MongoDB集合中的任何字段或⽂档的⼦字段进⾏索引。

操作

  • 创建索引

db.集合名称.createIndex(keys, options)
db.集合名称.createIndex({"title":1,"description":-1})

说明: 语法中 Key 值为你要创建的索引字段,1 为指定按升序创建索引,如果你想按降序来创建索引指定为 -1 即可。

createIndex() 接收可选参数,可选参数列表如下 :

MongoDB入门到使用

  • 查看集合索引

 db.集合名称.getIndexes()
  • 查看集合索引⼤⼩

db.集合名称.totalIndexSize()
  • 删除集合所有索引

db.集合名称.dropIndexes()
  • 删除集合指定索引

db.集合名称.dropIndex("索引名称")

复合索引

⼀个索引的值是由多个 key 进⾏维护的索引的称之为复合索引

 db.集合名称.createIndex({"title":1,"description":-1})

注意: mongoDB 中复合索引和传统关系型数据库⼀致都是左前缀原则

📄聚合

MongoDB 中聚合(aggregate)主要⽤于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。有点 类似 SQL 语句中的 count(*)。

使⽤

{
   _id: ObjectId(7df78ad8902c)
   title: 'MongoDB Overview', 
   description: 'MongoDB is no sql database',
   by_user: 'runoob.com',
   url: 'http://www.runoob.com',
   tags: ['mongodb', 'database', 'NoSQL'],
   likes: 100
},
{
   _id: ObjectId(7df78ad8902d)
   title: 'NoSQL Overview', 
   description: 'No sql database is very fast',
   by_user: 'runoob.com',
   url: 'http://www.runoob.com',
   tags: ['mongodb', 'database', 'NoSQL'],
   likes: 10
},
{
   _id: ObjectId(7df78ad8902e)
   title: 'Neo4j Overview', 
   description: 'Neo4j is no sql database',
   by_user: 'Neo4j',
   url: 'http://www.neo4j.com',
   tags: ['neo4j', 'database', 'NoSQL'],
   likes: 750
}

现在我们通过以上集合计算每个作者所写的文章数,使用aggregate()计算结果如下:

db.集合名称.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])

常⻅聚合表达式

MongoDB入门到使用

📐整合SpringBoot应⽤

环境搭建

引⼊依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

编写配置

# mongodb 没有开启任何安全协议# mongodb(协议)://121.5.167.13(主机):27017(端⼝)/baizhi(库名)spring.data.mongodb.uri=mongodb://121.5.167.13:27017/baizhi# mongodb 存在密码#spring.data.mongodb.host=tx.chenyn.cn#spring.data.mongodb.port=27017#spring.data.mongodb.database=baizhi#spring.data.mongodb.username=root#spring.data.mongodb.password=root

集合操作

创建集合

@Test
public void testCreateCollection(){
 mongoTemplate.createCollection("users");//参数: 创建集合名称
}

注意:创建集合不能存在,存在报错

删除集合

@Test
public void testDeleteCollection(){
 mongoTemplate.dropCollection("users");
}

相关注解

  • @Document

  • 修饰范围: ⽤在类上

  • 作⽤: ⽤来映射这个类的⼀个对象为 mongo 中⼀条⽂档数据

  • 属性:( value 、collection )⽤来指定操作的集合名称

  • @Id

  • 修饰范围: ⽤在成员变量、⽅法上

  • 作⽤: ⽤来将成员变量的值映射为⽂档的_id 的值

  • @Field

  • 修饰范围: ⽤在成员变量、⽅法上

  • 作⽤: ⽤来将成员变量以及值映射为⽂档中⼀个key、value对

  • 属性: ( name,value )⽤来指定在⽂档中 key 的名称,默认为成员变量名

  • @Transient

  • 修饰范围: ⽤在成员变量、⽅法上

  • 作⽤ : ⽤来指定改成员变量,不参与⽂档的序列化

⽂档操作

  • 添加

@Test
public void testSaveOrUpdate(){
 User user = new User(1, "小鸭子", 2000.1, new Date());
 User userDB = mongoTemplate.save(user);//返回保存的对象 insert or save

 List<User> users = Arrays.asList(
    new User(3, "大鸭子", 2000.1, new Date()), new User(4, "中鸭子", 2000.1, new Date())
    );
 mongoTemplate.insert(users,User.class); // 批量插入
}

insert: 插⼊重复数据时: insertDuplicateKeyException 提示主键重复; save 对已存在的数据 进⾏更新。 save: 批处理操作时: insert 可以⼀次性插⼊整个数据,效率较⾼; save 需遍历整个数据,⼀次插 ⼊或更新,效率较低。

  • 查询

  • Criteria

MongoDB入门到使用

  • 常⻅查询

@Test
    public void testFind(){
        // 查询所有
        List<User> users = mongoTemplate.findAll(User.class);

        // 根据id查询
        User user = mongoTemplate.findById(5, User.class);

        //查询所有
        mongoTemplate.findAll(User.class);
        mongoTemplate.find(new Query(),User.class);

        //等值查询
        mongoTemplate.find(Query.query(Criteria.where("name").is("小黄鸭")), User.class);

        // < > <= >= 查询
        mongoTemplate.find(Query.query(Criteria.where("age").lt(100)), User.class);

        // and 查询
        mongoTemplate.find(Query.query(Criteria.where("name").is("小黄鸭").and("age").is(20)), User.class);

        // or 查询
        Criteria criteria = new Criteria();
        criteria.orOperator(
                Criteria.where("name").is("小黄鸭"),
                Criteria.where("name").is("大黄鸭")
        );
        mongoTemplate.find(Query.query(criteria), User.class);

        //and or
        Criteria criteria1 = new Criteria()
                .and("age").is(23)
                .orOperator(
                        Criteria.where("name").is("小黄鸭"),
                        Criteria.where("name").is("大黄鸭"));
        mongoTemplate.find(Query.query(criteria1), User.class);

        // 排序
        Query querySort = new Query();
        querySort.with(Sort.by(Sort.Order.desc("age")));
        mongoTemplate.find(querySort, User.class);

        //skip limit 分⻚
        Query queryPage = new Query();
        queryPage.with(Sort.by(Sort.Order.desc("age")))//desc 降序 asc 升序
                .skip(0) //起始条数
                .limit(2); //每⻚显示记录数
        mongoTemplate.find(queryPage, User.class);

        //count 总条数
        mongoTemplate.count(new Query(), User.class);

        //distinct 去重
        //参数 1:查询条件 参数 2: 去重字段 参数 3: 操作集合 参数 4: 返回类型
        mongoTemplate.findDistinct(new Query(), "name", User.class, String.class);

        //使⽤ json 字符串⽅式查询
        Query query = new BasicQuery(
                "{$or:[{name:'小黄鸭'},{name:'大黄鸭'}]}",
                "{name:0}");
        mongoTemplate.find(query, User.class);
    }
  • 更新

    @Test
    public void testUpdate1(){
        //1.更新条件
        Query query = Query.query(Criteria.where("age").is(23));
        //2.更新内容
        Update update = new Update();
        update.set("name","小黄鸭");
        //单条更新
        mongoTemplate.updateFirst(query, update, User.class);
        //多条更新
        mongoTemplate.updateMulti(query, update, User.class);
        //更新插⼊
        mongoTemplate.upsert(query,update,User.class);
        //返回值均为 updateResult
        //System.out.println("匹配条数:" + updateResult.getMatchedCount());
        //System.out.println("修改条数:" + updateResult.getModifiedCount());
        //System.out.println("插⼊id_:" + updateResult.getUpsertedId());
    }
  • 删除

@Test
public void testDelete(){
 //删除所有
 mongoTemplate.remove(new Query(),User.class);
 //条件删除
 mongoTemplate.remove(
 Query.query(Criteria.where("name").is("编程不良⼈")),
 User.class
 );
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/154444.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!