MongoDB数据库基础

一、基础知识

1.1、什么是MongoDB

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

特点

  • 海量存储:方便扩展,多节点部署,形成集群
  • 文档数据库:数据结构由键值(key=>value)对组成
  • 支持RUBY,PYTHON,JAVA,C++,PHP,C#等多种语言
  • 可以直接允许JavaScript脚本

1.2、组成

MongoDB数据库基础

1.3、文档

官方定义

  • 文档是一个键值(key-value)对
  • 以二进制的JSON存储(BSON)

示例

{
 "usernaem";"李明",
 "age":21,
 "sex":"男",
 "email":"liming@example.com",
 "address":"南大街43号",
 "company":{
   "name": "科技公司",
   "industry":"互联网"
 }
}

键的命名要求

  • 不能含有\0(空字符)
  • 避免.$_x(下划线开头)

文档的特点

  • 键值(key-value)对是有序的
  • 键(key)唯一,不可重复
  • 键区分类型和大小写
  • 文档可以嵌套

数据类型
MongoDB数据库基础

ObjectId

  • 特点及用途:小,几乎唯一,可快速生成,方便排序(常用于文档的主键)
  • 生成规则:系统当前时间(秒) + 随机数 + 自增值
  • 常用方法:getTimestamp():获取时间、str:获取ObjectId的字符串
    MongoDB数据库基础
    MongoDB数据库基础

1.4、集合

  • 官方定义:集合就是MongoDB中的文档组
  • 理解集合:【集合】类似于关系数据中的表
  • 对比关系型数据库:集合中的文档【没有】固定的结构

命名规则

  • 不能包含\0字符(空字符"")
  • 不能使用system.的前缀(系统保留)
  • 建议不包含保留字 “$”
  • 用 . 分割不同命名空间的子集合(如:blog.users,blog.posts)

1.5、数据库

  • 多个文档组成集合,多个集合组成数据库
  • 一个实例可以承载多个数据库(逻辑库)
  • 每个数据库都有独立的权限
  • 保留的数据库名称(admin,local,config)

1.6、MongoDB与MySQL术语比较

MongoDB数据库基础


二、MongoDB安装及配置

2.1、安装

2.2、启动

系统服务启动
MongoDB数据库基础

命令行启动(需要以管理员身份运行)

net start/stop MongoDB

三、数据库管理

3.1、Mongo Shell

MongoDB自带的命令行管理工具

  • 第一步,进入MongoDB安装目录/bin
  • 第二步,打开命令行窗口,输入mongo --host 127.0.0.1 --port 27017,如果是默认安装可以直接输入mongo

可以直接把MongoDB安装目录/bin,加入到环境变量Path中,就可以随时通过命令行,输入mongo就可以连接。

3.2、图形化管理工具

  • Navicat
  • Robo 3T(免费)
  • Studio 3T(收费)

3.3、数据库管理

  • 查看所有数据库:show dbs
  • 创建/切换数据库:use db_name
  • 获取当前正在操作的数据库:db
  • 删除数据库:db.dropDatabase()

3.4、集合管理

  • 查看所有集合:show collections
  • 创建集合(当插入数据时会自动创建):db.createCollection("students")
  • 删除集合:db.COLLECTION_NAME.drop(),COLLECTION_NAME,实际集合的名称
  • 重命名集合:db.COLLECTION_NAME.renameCollection("temp")
  • 为集合中的某些域(列)创建索引:db.COLLECTION_NAME.createIndex(keys, <options>, <commitQuorum>)

四、数据管理

4.1、插入数据

插入单条数据

语法参考:db.COLLECTION_NAME.insertOne(document)

返回结果:
{ "acknowledged" : true, "insertedId" : ObjectId("60fe0c40fe9b36874a43644f") }

插入多条数据

语法参考:db.COLLECTION_NAME.insertMany([doc1, doc2])

返回结果:
{ "acknowledged" : true, "insertedId" : [ObjectId("..."), ObjectId("...")] }

4.2、查询数据

数据文件grades.txt,提取码:eh5t

数据文件students.txt,提取码:d4h3

4.2.1、查询一条/多条数据

查询一条数据

语法参考:db.COLLECTION_NAME.findOne(<filter>, <projection>)

参数解释

  • filter:查询条件(可选参数)
  • projection:需要返回的域(字段)(可选参数)

示例

//查询第一条数据
db.students.findOne();
//指定显示的列
db.students.findOne({},{"stu_no":1, "stu_name":1, "address":1});
//指定显示的列,指定_id不显示
db.students.findOne({},{"stu_no":1, "stu_name":1, "address":1, "_id":0});

查询所有数据

语法参考:db.COLLECTION_NAME.find({})

格式化显示(带缩进):db.COLLECTION_NAME.find().pretty()

4.2.2、条件查询

查询条件

  • 比较运算符
    MongoDB数据库基础
    示例代码

    // 查询年龄大于12岁的所有学生
    db.students.find({"age": {$gt: 12}});
    
    // 查询年龄在9~12之间(含)的学生信息
    db.students.find({"age": {$gte: 9, $lte: 12}});
    
    // 查询未设置/已设置年龄的学生信息
    db.students.find({"age": null});
    db.students.find({"age": {$ne: null}});
    
    // 查询学生年龄在9岁和12岁的学生信息
    db.students.find({"age": {$in: [9, 12]}});
    
  • 逻辑运算符
    MongoDB数据库基础

    // 查询所有12岁以上的男生和9岁以下的女生
    db.students.find({
    	$or:[
    		{"sex": "男", "age": {"$gt": 12}},
    		{"sex": "女", "age": {"$lt": 9}}
    	]
    });
    
  • 支持JavaScript正则表达式

    // 查找所有姓“李”的学生信息
    db.students.find({stu_name: /^李/});
    
    // 查找所有姓“李”, 名只有一个字的学生信息
    db.students.find({stu_name: /^李.$/});
    
    // 查找姓名中包含“雪”字的学生信息
    db.students.find({stu_name: /雪/});
    
  • 嵌套文档查询,使用点号(.)分割key
    示例代码:db.COLLECTION_NAME.find({"a.b": "c"})

    // 查询所有学生的语文成绩
    db.grades.find({"grade.course_name": "语文"});
    
    // 查找所有学生中语文成绩已经及格的学生信息
    db.grades.find({"grade.course_name": "语文", "grade.score": {$gte: 60}});
    
    db.grades.find({$and: [
    	{"grade.course_name": "语文"},
    	{"grade.score": {$gte: 60}}
    ]});
    
  • 在数组内查询
    MongoDB数据库基础

    // 查询只有两门成绩的学生信息
    db.students.find({grades: {$size: 2}});
    

4.2.3、聚合统计

  • 查看集合中文档的数量,可以链式调用

    db.COLLECTION_NAME.count()
    
  • 去掉重复的内容

    db.COLLECTION_NAME.distinct(field_name, <filter>)
    

示例

// 查询只有两门成绩的学生信息
db.students.find({grades: {$size: 2}});

// 统计学生总数
db.students.count();

// 查询只有两门成绩的学生信息总人数
db.students.find({grades: {$size: 2}}).count();

// 查找“三年级一班”学生的居住区域
db.students.distinct("address", {"class_name": "三年级一班"});

语法参考

db.COLLECTION_NAME.aggregate([
	// where
	{$match: {"grade.score":{$gte: 60}}},
	// group by
	{$group: {_id : "$stu_no", total: {$sum: 1}}},
	// having
	{$match: {total: {$eq: 3}}}
])

内置聚合统计函数
MongoDB数据库基础

// 统计语文成绩的最高分/最低分/平均分
db.grades.aggregate([
	// where
	{$match: {"grade.course_name": "语文"}},
	// group by
	{$group: {
		_id: null, 
		maxSource: {$max: "$grade.score"},
		minSource: {$min: "$grade.score"},
		avgSource: {$avg: "$grade.score"},
	}},
]);

// 统计张三各科总分
db.grades.aggregate([
	// where
	{$match: {"stu_name": "张三"}},
	// group by
	{$group: {
		_id: null, 
		maxSource: {$sum: "$grade.score"},
	}},
]);

// 统计每个班的学生人数
db.students.aggregate([
	// group by
	{$group: {
		_id: "$class_name", 
		total: {$sum: 1},
	}},
]);

// 统计每个班男生、女生总人数
db.students.aggregate([
	// group by
	{$group: {
		_id: {class_name: "$class_name", sex: "$sex"}, 
		total: {$sum: 1},
	}},
]);

// 查找三门成绩都及格(>=60)的学生
db.grades.aggregate([
	// where
	{$match: {"grade.score": {$gte: 60}}},
	// group by
	{$group: {
		_id: "$stu_no", 
		total: {$sum: 1},
	}},
	// having
	{$match: {total: {$eq: 3}}}
]);

4.3.4、排序和分页

排序

语法参考:db.COLLECTION_NAME.find().sort({field: value})

排序规则

  • 1:升序
  • -1:降序

示例

// 将学生的语文成绩从高到低排序
db.grades.find({"grade.course_name": "语文"}).sort({"grade.score": -1});

// 将学生的语文成绩按照年龄和成绩排序
db.grades.find({"grade.course_name": "语文"}).sort({"grade.score": -1, "age": -1});

分页

语法参考:db.COLLECTION_NAME.find().skip(10).limit(10)

方法解释

  • skip(N):跳过N行数据
  • limit(N):取N行数据
// 获取第三页学生成绩信息,每页8条
db.grades.find().skip(16).limit(8);

4.3、更新数据

以下三种方法使用上类似,以updateMany方法为例

  • updateOne():更新一条数据
  • replaceOne():替换一条数据
  • updateMany():更新多条数据

语法参考:db.COLLECTION_NAME.updateMany(<filter>, <update>, <options>)

MongoDB数据库基础

参数解释

  • 第一个参数:<filter>,查询条件,修改满足条件的数据
  • 第二个参数:<update>,需要修改的数据对象

更新数据表达式
MongoDB数据库基础
示例

// 创建users集合,并插入文档数据
db.users.insertMany([{"username": "cjw", "age": 12},{"username": "cjw01", "age": 13},{"username": "cjw02", "age": 14},{"username": "cjw03", "age": 15}]);

db.users.insertMany([{"username": "cjw04", "age": 16, "hobby": ["篮球", "足球"], "company": {"address": "明珠街"}}]);

// 设置用户的年龄为20岁
db.users.updateMany({}, {$set: {"age": 20}});

// 删除用户的爱好和公司信息
db.users.updateMany({}, {$unset: {"company": null, "hobby": null}});

// 添加用户created_at为系统当前时间
db.users.updateMany({}, {$currentDate: {"created_at": true}});

// 将用户的年龄+1
db.users.updateMany({}, {$inc: {"age": 1}});

4.4、删除数据

删除单条数据

语法参考:db.COLLECTION_NAME.deleteOne(<filter>)

批量删除数据

语法参考:db.COLLECTION_NAME.deleteMany(<filter>)

删除集合中所有的数据:db.COLLECTION_NAME.deleteMayn({})

练习

//查询年龄在9~12之间(含)的学生信息(学号,姓名,年龄和班级)
db.students.find({"age": {$gte: 9, $lte: 12}},{"stu_no":1, "stu_name":1, "age":1, "class_name":1});
上一篇:mysql数据库操作四


下一篇:十一:DDL语言(用于对数据库和表的管理和操作)