MongoDB从入门到精通

目录

一.MongoDB基础

1.概念

2.存储结构

3.特点

4.MongoDB的基本概念(数据库、集合、文档)

二.MongoDB语法

1.数据库

2.集合

3.文档

三.MongoDB高级查询

1.关系表达式

2.逻辑表达式

 

3.排序

4.分页查询

5.统计

四.MongoDB索引

1.简介

2.查看索引

3.创建索引

4.删除索引

5.查看执行计划

6.复合索引的创建

五.Springboot整合MongoDB

1.引入pom坐标

2.修改配置文件

3.定义实体类映射mongo的集合

4.定义查询方法

5.测试


 

一.MongoDB基础

1.概念

        MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。

2.存储结构

        MongoDB将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB文档类似于JSON 对象。字段值可以包含其他文档,数组及文档数组。

9efd0ab7b1dd4886bdcd38ef490fe362.png

3.特点

(1)索引数据结构为: B-tree 。

(2)支持索引和次级索引(secondary indexes): 次级索引是指文档或row有一个主键( primarykey )作为索引,同时允许文档或row内部还拥有一个索引,提升查询的效率。

4.MongoDB的基本概念(数据库、集合、文档)

 

 下面看下mongodb中的概念与传统数据的比对吧

70d22b0624ce4be78b23277b5310a409.png

二.MongoDB语法

1.数据库

(1)概念:一个mongoDB的实例可以运行多个database,database之间是完全独立的,每个database有自己的权限,每个database存储于磁盘的不同文件。

(2)操作:

查看数据库列表

show dbs;

显示当前数据库

db

创建数据库

        MongoDB 使用 use 命令创建数据库,如果数据库不存在,MongoDB 会在第一次使用该数据库时创建数据库。如果数据库已经存在则连接数据库,然后可以在该数据库进行各种操作。

use testdb;

        注意: 在 MongoDB 中,只有在数据库中插入集合后才会创建! 就是说,创建数据库后要再插入一个集合,数据库才会真正创建。

插入数据

db.testdb.insertOne({"name":"张三"});

删除数据库

use testdb;
db;
#删除数据库
db.dropDatabase();

2.集合

(1)概念:相当于关系数据库的表,不过没有数据结构的定义。它由多个document组成。

(2)操作:

创建集合

可以通过 db.createCollection(name,option) 创建集合
name: 要创建的集合名称
options: 可选参数, 指定有关内存大小及索引的选项

举例:db.createCollection("blog"); //创建一个blog的集合

查看集合

show collections;
show tables;

删除集合

db.collection.drop()
collection为集合名称
举例:db.blog.drop()

3.文档

(1)概念: mongoDB的基本单位,相当于关系数据库中的行,它是一组有序的key/value键值对,使用json格式,如:{"foo" : 3, "greeting": "Hello, world!"}。

(2) 基础操作

插入数据

1.单条数据插入
insertOne(推荐)

db.blog.insertOne({
    "title": "MySql 教程",
    "description": "Mysql是一个传统数据库",
    "by": "我的博客",
    "url": "http://www.baiyp.ren",
    "tags": [
        "Mysql",
        "database"
    ],
    "likes": 10000
});

2.批量插入
insertMany(推荐)
db.blog.insertOne([
    {
        "title": "MySql 教程1",
        "description": "Mysql是一个传统数据库2",
        "by": "我的博客",
        "url": "http://www.baiyp.ren",
        "tags": [
            "Mysql",
            "database"
        ],
        "likes": 10000
    },
    {
        "title": "MySql 教程2",
        "description": "Mysql是一个传统数据库2",
        "by": "我的博客",
        "url": "http://www.baiyp.ren",
        "tags": [
            "Mysql",
            "database"
        ],
        "likes": 10000
    },
]);

查询文档

//查询所有
db.blog.find();

//美化查询结果
db.blog.find().pretty();

//只查询第一个文档
db.blog.findOne();

//等值查询
db.blog.find({
    "title": "MySql 教程2"
}).pretty();

//投影查询如下
//只显示title列的数据
db.blog.find({"title":"MySql 教程2"},{"title":1}).pretty();
//只显示title和description列的数据
db.blog.find({"title":"MySql 教程2"},{"title":1,"description":1}).pretty();
//不显示 title和description列的数据
db.blog.find({"title":"MySql 教程2"},{"title":0,"description":0}).pretty();

更新文档

//根据id更新
db.blog.update({"_id":"1"},{$set:{"likes":666}})

//save更新
//save() 方法通过传入的文档来替换已有文档,_id 主键存在就更新,不存在就插入
db.blog.save({
    "_id": "1",
    "title": "MySql 传统教程教程3",
    "description": "Mysql是一个传统数据库",
    "by": "我的博客",
    "url": "http://www.baiyp.ren",
    "tags": [
        "Mysql",
        "database"
    ],
    "likes": 100000
});

删除文档 

//删除指定文档
db.blog.remove({"_id":"1"});
//删除复合条件的第一个文档
db.blog.deleteOne({});


//删除全部文档
db.blog.remove({});
//删除复合条件的所有文档
db.blog.deleteMany({});

三.MongoDB高级查询

1.关系表达式

(1)等于

        等于的操作符是 $eq ,我们可以查询城市名称是 CUSHMAN 的数据 

db.zips.find({
    "city": {
        "$eq": "CUSHMAN"
    }
}).pretty();

(2)小于

        小于的操作符号是 $lt ,我们查询城市人数小于 10万的城市有哪些

db.zips.find({
    "pop": {
        "$lt": 10
    }
}).pretty();

(3)小于等于

        小于等于的操作符号是 $lte ,我们查询城市没有人的城市,也就是小于等于0的城市

db.zips.find({
    "pop": {
        "$lte": 0
    }
}).pretty();

(4)不等于

        不等于的操作符号是 $ne ,我们可以搜索城市人数不是0的城市

db.zips.find({
    "pop": {
        "$ne": 0
    }
}).pretty();

(5)包含查询

IN查询的符号是 $in ,使用方式如下
db.zips.find({
    "state": {
        "$in": [
            "MA",
            "NY"
        ]
    }
}).pretty();

(6)不包含查询

NIN相当于MySQL的 NOT IN 查询,操作符号是 $nin ,我们查询城市名称缩写不是 MA 以及 NY 的文档

db.zips.find({
    "state": {
        "$nin": [
            "MA",
            "NY"
        ]
    }
}).pretty();

(7)判断字段存在

mongodb是一个文档型数据库,对于表结构没有严格定义,有时候可能缺少字段,如果要查询缺失的字段可以使用 $exists 判断字段是否存在

db.zips.find({
    "state": {
        "$exists": false
    }
}).pretty();

(8)多条件查询

db.zips.find({
    "pop": {
        "$gte": 10,
        "$lt": 50
    }
}).pretty();

 

2.逻辑表达式

(1)and

        AND的标准写法的操作符是 $and ,下面是查询,我们查询 州缩写是 NY 并且人数大于一亿的文档。

db.zips.find({
    "$and": [
        {
            "state": "NY"
        },
        {
            "pop": {
            "$gt": 100000
            }
        }
    ]
}).pretty();

(2)or

        MongoDB OR 条件语句使用了关键字 $or,我们查询人数小于0 或者城市缩写是 NY 的城市。

db.zips.find({
    "$or": [
        {
            "state": "NY"
        },
        {
            "pop": {
            "$lt": 0
            }
        }
    ]
}).pretty();

(3)not

        $not 是NOT的操作符,和其他的用法不太一样,使用方法如下

       查询人数 小于十万人的城市

db.zips.find({
    "pop": {
        "$not": {
            "$gte": 10
        }
    }
}).pretty();

(4)多个条件表达式

实现如下sql的效果表达式举例

select * from zips where (state='NY' and pop>10 and pop <= 50) or (state
in('MD','VA') and pop>10 and pop <= 50)
db.zips.find({
"$or": [
	{
		"$and": [
			{
				"state": "NY"
			},
			{
				"pop": {
					"$gt": 10,
					"$lte": 50
				}
			}
		]
	},
	{
		"$and": [
			{
				"state": {
					"$in": [
						"MD",
						"VA"
					]
				}
			},
			{
				"pop": {
					"$gt": 10,
					"$lte": 50
				}
			}
		]
	}
]
}).pretty();

 

3.排序

        在MongoDB中使用sort()方法对数据进行排序,sort()方法可以通过参数指定排序的字段,并使用1 和 -1 来指定排序的方式,其中 1 为升序排列,而-1是用于降序排列。

语法格式

db.COLLECTION_NAME.find().sort({KEY1:1,KEY2:-1,....});

(1)升序查询

按照城市人口升序查询

db.zips.find().sort({
    "pop": 1
}).pretty();

(2)降序查询

按照城市人口降序查询

db.zips.find().sort({
    "pop": -1
}).pretty();

(3)组合查询

我们查询人数大于1000万,并且先按照城市缩写升序排,如果城市缩写相同再按照人数降序排

db.zips.find({
    "pop": {
    "$gt": 1000
    }
}).sort({
    "state": 1,
    "pop": -1
}).pretty();

4.分页查询

MongoDB提供了skip()和limit()方法。

skip: 跳过指定数量的数据. 可以用来跳过当前页之前的数据,即跳过pageSize*(n-1)。

limit: 指定从MongoDB中读取的记录条数,可以当做页面大小pageSize。

根据id排序查询前30条的数据

db.zips.find({},{"_id":1}).limit(30);

分页语句

#第一页数据
db.zips.find({},{_id:1}).sort({"_id":1}).limit(10);
# 第二页数据
db.zips.find({"_id":{$gt:"20"}},{_id:1}).sort({"_id":1}).limit(10);
# 第三页数据
db.zips.find({"_id":{$gt:"30"}},{_id:1}).sort({"_id":1}).limit(10);

5.统计

(1)count

查询记录的总数,下面条件是查询人数小于十万人的城市的数量

//写法1
db.zips.find({
    "pop": {
        "$not": {
            "$gte": 10
        }
    }
}).count();

//写法2
db.zips.count({
    "pop": {
        "$not": {
            "$gte": 10
        }
    }
});

(2)distinct

        按照state字段进行去重后的数据

db.zips.distinct("state");

        有条件去重:对于城市人数是七千万以上的城市的缩写去重

db.zips.distinct("state",{
    "pop": {
        "$gt": 70000
    }
});

四.MongoDB索引

1.简介

        在创建集合期间,MongoDB 在  _id 字段上 创建唯一索引,该索引可防止客户端插入两个具有相同值的文档。

2.查看索引

//查看集合索引
db.zips.getIndexes();

//查看数据库中所有集合的所有索引,需在 MongoDB 的 Shell 客户端执行以下语句
db.getCollectionNames().forEach(function(collection){
    indexes = db[collection].getIndexes();
    print("Indexes for [" + collection + "]:" );
    printjson(indexes);
});

3.创建索引

就根据 pop 字段创建了一个升序索引

db.zips.createIndex({"pop":1})
//创建一个名称是 pop_union_index 的索引,按照 pop 字段降序,并且在5秒后删除
db.zips.createIndex(
    {
        "pop":-1   //降序
    },
    {
        "name":"pop_union_index",  //索引名称
        "expireAfterSeconds":5     //TTL时间 5s后删除
    }
)

4.删除索引

//根据索引的名字进行索引删除
db.zips.dropIndex("date_expire")

//根据字段进行删除索引
db.zips.dropIndex ({ "pop" : 1 })

//db.collection.dropIndexes() 可以把集合所有索引删除
db.zips.dropIndexes()

5.查看执行计划

db.zips.find({
    "pop": {
        "$gt": 10000
    }
}).explain();

c32f74b399834e97b15951963bcd6590.png

6.复合索引的创建

创建一个以 city 升序, state 降序的复合索引

db.zips.createIndex({
    "city": 1,
    "state": -1
})

在MySQL中存在最佳左前缀法则,在mongodb中查询同样生效

 

五.Springboot整合MongoDB

1.引入pom坐标

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

2.修改配置文件

spring:
    application:
        name: spring-boot-test
    data:
        mongodb:
            database: test
            host: 127.0.0.1
            port: 27017

3.定义实体类映射mongo的集合

package com.itheima.mongo.domain;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

/**
 * @author tangbb
 * @date 2022/9/14
 */
@Document
public class Blog {
    @Id
    private String id;
    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

4.定义查询方法

package com.itheima.mongo.controller;

import com.itheima.mongo.domain.Blog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;


/**
 * @author tangbb
 * @date 2022/9/14
 */
@RestController
@RequestMapping("/mongo")
public class MongoDemoController {
    @Autowired
    private MongoTemplate mongoTemplate;

    @RequestMapping("/{id}")
    @ResponseBody
    public String getBlogInfo(@PathVariable("id") String id) {
        Blog blog = mongoTemplate.findById(id, Blog.class);
        return blog.toString();
    }

}

5.测试

//1.造数据
use test;
db.blog.insertOne({"name":"张三"});
db.blog.insertOne({"name":"李四"});
//2.浏览器访问如下接口
http://localhost:8899/mongo/63218413a83100003a0015cb

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Mr Tang

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

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

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

打赏作者

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

抵扣说明:

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

余额充值