0
点赞
收藏
分享

微信扫一扫

MongoDB--基础篇

兮城 2022-05-13 阅读 71

MongoDB相关概念

业务应用场景

传统的关系型数据库(如​​MySQL​​​),在数据操作的“三高”需求以及应对​​Web2.0​​的网站需求面前,显得力不从心。

解释:“三高”需求:

  • High performance - 对数据库高并发读写的需求。
  • Huge Storage - 对海量数据的高效率存储和访问的需求。
  • High Scalability && High Availability- 对数据库的高可扩展性和高可用性的需求。

而MongoDB可应对“三高”需求。


具体的应用场景如:

1)社交场景,使用 ​​MongoDB ​​存储存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能。

2)游戏场景,使用​​ MongoDB​​ 存储游戏用户信息,用户的装备、积分等直接以内嵌文档的形式存储,方便查询、高效率存储和访问。

3)物流场景,使用 ​​MongoDB​​​ 存储订单信息,订单状态在运送过程中会不断更新,以​​MongoDB​​内嵌数组的形式来存储,一次查询就能将

订单所有的变更读取出来。

4)物联网场景,使用 ​​MongoDB ​​存储所有接入的智能设备信息,以及设备汇报的日志信息,并对这些信息进行多维度的分析。

5)视频直播,使用​​MongoDB​​存储用户信息、点赞互动信息等。



这些应用场景中,数据操作方面的共同特点是:

(1)数据量大

(2)写入操作频繁(读写都很频繁)

(3)价值较低的数据,对事务性要求不高

对于这样的数据,我们更适合使用​​MongoDB​​来实现数据的存储。

???? 什么时候选择MongoDB


在架构选型上,除了上述的三个特点外,如果你还犹豫是否要选择它?可以考虑以下的一些问题:

应用不需要事务及复杂​​join​​支持

新应用,需求会变,数据模型无法确定,想快速迭代开发

应用需要​​2000-3000​​​以上的读写​​QPS​​(更高也可以)

应用需要TB甚至 PB 级别数据存储

应用发展迅速,需要能快速水平扩展

应用要求存储的数据不丢失

应用需要99.999%高可用

应用需要大量的地理位置查询、文本查询

如果上述有1个符合,可以考虑 ​​MongoDB​​​,2个及以上的符合,选择​​ MongoDB​​ 绝不会后悔。



MongoDB简介


​ MongoDB​​​是一个开源、高性能、无模式的文档型数据库,当初的设计就是用于简化开发和方便扩展,是​​NoSQL​​​数据库产品中的一种。是最像关系型数据库​​(MySQL)​​的非关系型数据库。

它支持的数据结构非常松散,是一种类似于​​JSON​​​的 格式叫​​BSON​​,所以它既可以存储比较复杂的数据类型,又相当的灵活。

​MongoDB​​​中的记录是一个文档,它是一个由字段和值对​​(fifield:value)​​​组成的数据结构。​​MongoDB​​​文档类似于​​JSON​​对象,即一个文档认为就是一个对象。字段的数据类型是字符型,它的值除了使用基本的一些类型外,还可以包括其他文档、普通数组和文档数组。



体系结构

???? MySQL和MongoDB的对比:

MongoDB--基础篇_MongoDB

SQL术语概念

MongoDB术语/概念

解释/说明

database

database

数据库

table

collection

数据库表/集合

row

document

数据记录行/文档

column

field

数据字段/域

index

index

索引

table joins

表连接,MongoDB不支持

嵌入文档

MongoDB通过嵌入式文档来替代多表连接

primary key

primary key

主键,MongoDB自动将_id字段设置为主键


数据模型


​MongoDB​​​的最小存储单位就是文档(​​document​​​)对象,文档(​​document​​​)对象对应于关系型数据库的行。数据在​​MongoDB​​​中已​​BSON(Binary-JSON)​​文档的格式存储在磁盘上。

​BSON(Binary Serialized Document Format)​​​是一种类​​json​​​的一种二进制形式的存储格式,简称​​Binary JSON​​​。​​BSON​​​和​​JSON​​​一样,支持内嵌的文档对象和数组对象,但是​​BSON​​​有​​JSON​​​没有的一些数据类型,如​​Date​​​和​​BinData​​类型。

​Bson​​​中,除了基本的​​JSON​​​类型:string,integer,boolean,double,null,array和object,​​mongo​​还使用了特殊的数据类型。这些类型包括date,object id,binary data,regular expression 和code。每一个驱动都以特定语言的方式实现了这些类型,查看你的驱动的文档来获取详细信息。


​BSON​​数据类型参考列表:

数据类型

描述

举例

字符串

UTF-8字符串都可表示为字符串类型的数据

{"X":"foobar"}

对象id

对象id是文档的12字节的唯一ID

{"X" :ObjectId() }

布尔值

真或者假:true或者false

{"x":true}+

数组

值的集合或者列表可以表示成数组

{"x" : ["a", "b", "c"]}

32位整数

类型不可用。JavaScript仅支持64位浮点数,所以32位整数会被自动转换

shell是不支持该类型的,shell中默认会转换成64位浮点数

64位整数

不支持这个类型。shell会使用一个特殊的内嵌文档来显示64位整数

shell是不支持该类型的,shell中默认会转换成64位浮点数

64位浮点数

shell中的数字就是这一种类型

{"x":3.14159,"y":3}

null

表示空值或者未定义的对象

{"x":null}

undefifined

文档中也可以使用未定义类型

{"x":undefifined}

符号

shell不支持,shell会将数据库中的符号类型的数据自动转换成字符串

正则表达式

文档中可以包含正则表达式,采用JavaScript的正则表达式语法

{"x" : /foobar/i}

代码

文档中还可以包含JavaScript代码

{"x" : function() { /* …… */ }}

二进制数据

二进制数据可以由任意字节的串组成,不过shell中无法使用

最大值/最小值

BSON包括一个特殊类型,表示可能的最大值。shell中没有这个类型

提示:

shell默认使用64位浮点型数值。{“x”:3.14}或{“x”:3}。对于整型值,可以使用NumberInt(4字节符号整数)或NumberLong(8字节符号整数),​​{“x”:NumberInt(“3”)}{“x”:NumberLong(“3”)}​


MongoDB的特点

  • 高性能:
  • MongoDB提供高性能的数据持久性。特别是,

    对嵌入式数据模型的支持减少了数据库系统上的I/O活动。

    索引支持更快的查询,并且可以包含来自嵌入式文档和数组的键。(文本索引解决搜索的需求、TTL索引解决历史数据自动过期的需求、地理位置索引可用于构建各种 O2O 应用)

    mmapv1、wiredtiger、mongorocks(rocksdb)、in-memory 等多引擎支持满足各种场景需求。

    Gridfs解决文件存储的需求。

  • 高可用性:
  • MongoDB的复制工具称为副本集(replica set),它可提供自动故障转移和数据冗余。

  • 高扩展性:
  • MongoDB提供了水平可扩展性作为其核心功能的一部分。

    分片将数据分布在一组集群的机器上。(海量数据存储,服务能力水平扩展)

    从3.4开始,MongoDB支持基于片键创建数据区域。在一个平衡的集群中,MongoDB将一个区域所覆盖的读写只定向到该区域内的那些片。

  • 丰富的查询支持:
  • MongoDB支持丰富的查询语言,支持读和写操作(CRUD),比如数据聚合、文本搜索和地理空间查询等。

  • 其他特点:
  • 如无模式(动态模式)、灵活的文档模型、


MongoDB中的基本概念

???? 数据库


  • 一个​​mongodb​​中可以建立多个数据库。
  • ​MongoDB​​的默认数据库为"db",该数据库存储在data目录中
  • ​MongoDB​​的单个实例可以容纳多个独立的数据库,每一个都有自己的集合和权限,不同的数据库也放置在不同的文件中。


???? 集合


  • 集合就是​​MongoDB​​​文档组,类似于​​RDBMS​​(关系数据库管理系统:Relational Database Management System)中的表格。
  • 集合存在于数据库中,集合没有固定的结构,对集合可以插入不同格式和类型的数据,但通常情况下我们插入集合的数据都会有一定的关联性。

集合命名的时候应该注意:

  • 集合名不能是空字符串""。
  • 集合名不能含有\0字符(空字符),这个字符表示集合名的结尾。
  • 集合名不能以"system."开头,这是为系统集合保留的前缀。
  • 用户创建的集合名字不能含有保留字符。


???? 文档(document)


是一组键值(key-value)对(即​​BSON​​​)。​​MongoDB​​​的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型,这与关系型数据库有很大的区别,也是​​MongoDB​​非常突出的特点。

需要注意的是:

  • 文档中的键/值对是有序的。
  • 文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型。
  • MongoDB区分类型和大小写。
  • MongoDB的文档不能有重复的键。
  • 文档的键是字符串。



MongoDB部署

1.下载软件包

# wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.4.1.tgz

2.解压缩

# tar -xvzf mongodb-linux-x86_64-rhel70-4.4.1.tgz
# mv mongodb-linux-x86_64-rhel70-4.4.1 /usr/local/mongodb

3.创建数据目录、日志目录、配置文件存放目录

# mkdir /usr/local/mongodb/{data,conf,log}

4.编辑配置文件

# cat >>/usr/local/mongodb/conf/mongodb.conf<<EOF
dbpath=/usr/local/mongodb/data
logpath=/usr/local/mongodb/log/mongodb.log
bind_ip=0.0.0.0
port=27017
logappend=1
fork=1
EOF

5.添加环境变量

# vim /etc/profile
export MONGODB_HOME=/usr/local/mongodb
export PATH=$PATH:$MONGODB_HOME/bin
# source /etc/profile

6.启动

# mongod --config /usr/local/mongodb/conf/mongodb.conf
# ps -ef |grep mongo
root 3969694 1 0 10:19 ? 00:01:06 mongod --config /usr/local/mongodb/conf/mongodb.conf

✏️ 停止mongodb

停止服务的方式有两种:快速关闭和标准关闭
1.快速关闭方法(快速,简单,数据可能会出错)
目标:通过系统的kill命令直接杀死进程,杀完要检查一下,避免有的没有杀掉。
通过进程编号关闭节点
# kill -2 3969694

2.标准的关闭方法(数据不容易出错,但麻烦)
目标:通过mongo客户端中的shutdownServer命令来关闭服务
//客户端登录服务,注意,这里通过localhost登录,如果需要远程登录,必须先登录认证才行。
> mongo --port 27017
//#切换到admin库
> use admin
//关闭服务
> db.shutdownServer()

补充

如果一旦是因为数据损坏,则需要进行如下操作(了解):

1.删除lock文件

# rm -f /usr/local/mongodb/data/mongod.lock

2.修复数据

# mongod --repair --dbpath=/usr/local/mongodb/data/


常用命令

MongoDB库操作

???? MongoDB系统保留库说明:


系统保留数据库:可以直接访问这些有特殊作用的数据库。

  • admin:从权限的角度来看,这是"root"数据库
  • local:这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合;
  • config:当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。


✏️ 选择和创建数据库

> use 数据库名

如果数据库不存在,则创建数据库,否则切换到指定的数据库。

> use articledb

✏️ 查看当前服务器的所有数据库

> show databases

> show dbs

✏️ 查看当前正在使用的数据库

> db

✏️ 删除数据库

> db.dropDatabase()

备注:主要用来删除已经持久化的数据库

注意: 要删除哪个数据库,一定要先切换到要删除的数据库中,然后再进行​​db.dropDatabase()​


MongoDB集合操作

✏️ 集合的显示创建

基本语法:

> db.createCollection(name, options)

其中
- name:要创建的集合名称
- options:可选参数,指定有关内存大小及索引的选项(一下为可选参数列表)

options参数如下:

字段

类型

描述

capped

布尔

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

autoIndexld

布尔

(可选)如果为true,自动在_id字段创建索引。默认为true。

size

数值

(可选)为固定集合指定一个最大值,以千字节计(KB)。如果capped为true,也需要指定该字段。

max

数值

(可选)指定固定集合中包含文档的最大值。

???? 示例

创建一个集合testcol
> db.createCollection("testcol");
{ "ok" : 1 }

//创建集合student
> db.createCollection("student");
{ "ok" : 1 }

//创建固定大小的集合,创建固定集合mycol,整个集合空间大小6142800KB,文档最大个数为10000个。
> db.createCollection("mycol",{capped:true,size:6142800,max:10000});
{ "ok" : 1 }
> show tables;
mycol
student
testcol

//创建固定大小的集合,创建固定集合mycol02,整个集合空间大小6142800KB,文档最大个数为10000个。
> db.createCollection("mycol02",{capped:true,size:6142800,max:10000, autoIndexId:true});
{
"note" : "The autoIndexId option is deprecated and will be removed in a future release",
"ok" : 1
}

注意 在​​MongoDB​​中,集合只有在内容插入后才会创建! 就是说,创建集合(数据表)后要再插入一个文档(记录),集合才会真正创建。

✏️ 集合的隐式创建

当向一个集合中插入一个文档的时候,如果集合不存在,则会自动创建集合。


✏️ 集合的查看

> show collections
或者
> show tables


✏️ 集合的删除

集合删除语法格式如下:

> db.collection.drop()

> db.集合.drop()

如果成功删除选定集合,则drop()方法返回true,否则返回false.

例如:要删除testcol集合

> db.testcol.drop()
true


文档基本CRUD


文档(document)的数据结构和​​JSON​​​基本一样,所有存储在集合中的数据都是​​BSON​​格式。


文档的插入

✏️ 单个文档插入

语法如下:

db.COLLECTION_NAME.insert(document)

示例:

> use testcoll
switched to db testcoll
> db.student.insert({name:"小白",age:18,sdept:"计算机系",sex:"男",createdatetime:new Date()})
WriteResult({ "nInserted" : 1 })

> db.student.find()
{ "_id" : ObjectId("5fa125ec481bd6c96002a80b"), "name" : "小白", "age" : 18, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-03T09:42:04.517Z") }

✏️ 批量文档插入

语法如下:

db.COLLECTION_NAME.insertMany([document1, document2,...])

示例:

> db.student.insertMany(
[
{name:"张大仙",age:19,sdept:"计算机系",sex:"男",createdatetime:new Date()},
{name:"李太白",age:17,sdept:"计算机系",sex:"男",createdatetime:new Date()}
]
)

{
"acknowledged" : true,
"insertedIds" : [
ObjectId("5fa255ab45dc2c9556990f3f"),
ObjectId("5fa255ab45dc2c9556990f40")
]
}

> db.student.find()
{ "_id" : ObjectId("5fa125ec481bd6c96002a80b"), "name" : "小白", "age" : 18, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-03T09:42:04.517Z") }
{ "_id" : ObjectId("5fa255ab45dc2c9556990f3f"), "name" : "张大仙", "age" : 19, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }
{ "_id" : ObjectId("5fa255ab45dc2c9556990f40"), "name" : "李太白", "age" : 17, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }


文档的更新

语法如下:

db.COLLECTION_NAME.update(
<query>{键名:值},
<update>{$set:{键名:值}},
{
upsert:<boolean>,
multi:<boolean>
}
)
参数说明:
query:update的查询条件
update:update的对象和更新的操作符$set,可以理解为sql update查询内set后面的
upsert:可选,意思是,如果不存在update的记录,是否插入。true为插入,默认是false,不插入。
multi:可选,mongodb默认是false,只更新找到的第一条记录,如果为true,就把按条件查出来多条记录全部更新。

示例:

✏️ 修改匹配的第一条记录

> db.student.update(
{sex:"男"},
{$set:{sdept:"前端"}},
)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

> db.student.find()
{ "_id" : ObjectId("5fa125ec481bd6c96002a80b"), "name" : "小白", "age" : 18, "sdept" : "前端", "sex" : "男", "createdatetime" : ISODate("2020-11-03T09:42:04.517Z") }
{ "_id" : ObjectId("5fa255ab45dc2c9556990f3f"), "name" : "张大仙", "age" : 19, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }
{ "_id" : ObjectId("5fa255ab45dc2c9556990f40"), "name" : "李太白", "age" : 17, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }

✏️ 修改匹配的所有记录

> db.student.update(
{sex:"男"},
{$set:{sdept:"后端"}},
{multi:true}
)
WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 3 })

> db.student.find()
{ "_id" : ObjectId("5fa125ec481bd6c96002a80b"), "name" : "小白", "age" : 18, "sdept" : "后端", "sex" : "男", "createdatetime" : ISODate("2020-11-03T09:42:04.517Z") }
{ "_id" : ObjectId("5fa255ab45dc2c9556990f3f"), "name" : "张大仙", "age" : 19, "sdept" : "后端", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }
{ "_id" : ObjectId("5fa255ab45dc2c9556990f40"), "name" : "李太白", "age" : 17, "sdept" : "后端", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }

✏️ 匹配多个条件(同时满足)

> db.student.update(
{sex:"男", name:"小白"},
{$set:{sdept:"计算机系"}},
)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

> db.student.find()
{ "_id" : ObjectId("5fa125ec481bd6c96002a80b"), "name" : "小白", "age" : 18, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-03T09:42:04.517Z") }
{ "_id" : ObjectId("5fa255ab45dc2c9556990f3f"), "name" : "张大仙", "age" : 19, "sdept" : "后端", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }
{ "_id" : ObjectId("5fa255ab45dc2c9556990f40"), "name" : "李太白", "age" : 17, "sdept" : "后端", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }

✏️ 更新多个值

> db.student.update(
{sex:"男", name:"小白"},
{$set:{sdept:"英语系", age:22}},
)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

> db.student.find()
{ "_id" : ObjectId("5fa125ec481bd6c96002a80b"), "name" : "小白", "age" : 22, "sdept" : "英语系", "sex" : "男", "createdatetime" : ISODate("2020-11-03T09:42:04.517Z") }
{ "_id" : ObjectId("5fa255ab45dc2c9556990f3f"), "name" : "张大仙", "age" : 19, "sdept" : "后端", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }
{ "_id" : ObjectId("5fa255ab45dc2c9556990f40"), "name" : "李太白", "age" : 17, "sdept" : "后端", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }

✏️ 多个条件满足其中一个($or)

> db.student.update(
{$or:[{sex:19}, {name:"小白"}]},
{$set:{sdept:"数学系", age:22}},
)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

> db.student.find()
{ "_id" : ObjectId("5fa125ec481bd6c96002a80b"), "name" : "小白", "age" : 22, "sdept" : "数学系", "sex" : "男", "createdatetime" : ISODate("2020-11-03T09:42:04.517Z") }
{ "_id" : ObjectId("5fa255ab45dc2c9556990f3f"), "name" : "张大仙", "age" : 19, "sdept" : "后端", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }
{ "_id" : ObjectId("5fa255ab45dc2c9556990f40"), "name" : "李太白", "age" : 17, "sdept" : "后端", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }


文档的删除

语法如下:

db.COLLECTION_NAME.remove(
<query>,
{
justOne:<boolean>
}
)

参数说明:
query:(可选)删除的文档的条件,
justOne:(可选)如果设置为true或1,则只删除一个文档,如果不设置该参数,或使用默认值false,则删除所有匹配条件的文档。

示例:

✏️ 删除符合条件的第一条(justOne.true)

> db.student.remove(
{sex:"男"},
{justOne:true}
)
WriteResult({ "nRemoved" : 1 })

> db.student.find()
{ "_id" : ObjectId("5fa255ab45dc2c9556990f3f"), "name" : "张大仙", "age" : 19, "sdept" : "后端", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }
{ "_id" : ObjectId("5fa255ab45dc2c9556990f40"), "name" : "李太白", "age" : 17, "sdept" : "后端", "sex" : "男", "createdatetime" : ISODate("2020-11-04T07:18:03.528Z") }

✏️ 删除符合条件的所有记录

> db.student.remove(
{sex:"男"}
)

✏️ 删除所有记录

> db.student.remove({})


文档的查询


​MongoDB​​​查询文档使用​​find()​​​方法,使用​​findOne()​​查询一条数据

​find()​​方法以非结构化的方式来显示所有的文档

语法格式:

db.COLLECTION_NAME.find(query,projection)

注意:
query:可选,使用查询操作符指定查询条件
projection:可选,使用投影操作符指定返回的值
需要以格式化的方式来读取数据,可以使用pretty()方法。

查询前先造几条数据

db.student.insertMany(
[
{name:"张大仙",age:19,sdept:"计算机系",sex:"男",createdatetime:new Date()},
{name:"李太白",age:17,sdept:"计算机系",sex:"男",createdatetime:new Date()},
{name:"黄花",age:18,sdept:"英语系",sex:"女",createdatetime:new Date()},
{name:"菜花",age:20,sdept:"数学系",sex:"女",createdatetime:new Date()},
]
)

基本查询

✏️ 查询student集合中所有的文档

> db.student.find()
{ "_id" : ObjectId("5fa27688b808fba58f5a3a41"), "name" : "张大仙", "age" : 19, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T09:38:16.820Z") }
{ "_id" : ObjectId("5fa27688b808fba58f5a3a42"), "name" : "李太白", "age" : 17, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T09:38:16.820Z") }
{ "_id" : ObjectId("5fa27688b808fba58f5a3a43"), "name" : "黄花", "age" : 18, "sdept" : "英语系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T09:38:16.820Z") }
{ "_id" : ObjectId("5fa27688b808fba58f5a3a44"), "name" : "菜花", "age" : 20, "sdept" : "数学系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T09:38:16.820Z") }

✏️ 格式化方法显示查询结果

> db.student.find().pretty()
{
"_id" : ObjectId("5fa27688b808fba58f5a3a41"),
"name" : "张大仙",
"age" : 19,
"sdept" : "计算机系",
"sex" : "男",
"createdatetime" : ISODate("2020-11-04T09:38:16.820Z")
}
{
"_id" : ObjectId("5fa27688b808fba58f5a3a42"),
"name" : "李太白",
"age" : 17,
"sdept" : "计算机系",
"sex" : "男",
"createdatetime" : ISODate("2020-11-04T09:38:16.820Z")
}
{
"_id" : ObjectId("5fa27688b808fba58f5a3a43"),
"name" : "黄花",
"age" : 18,
"sdept" : "英语系",
"sex" : "女",
"createdatetime" : ISODate("2020-11-04T09:38:16.820Z")
}
{
"_id" : ObjectId("5fa27688b808fba58f5a3a44"),
"name" : "菜花",
"age" : 20,
"sdept" : "数学系",
"sex" : "女",
"createdatetime" : ISODate("2020-11-04T09:38:16.820Z")
}

✏️ 条件过滤查询

> db.student.find({sex:"男"})
{ "_id" : ObjectId("5fa27688b808fba58f5a3a41"), "name" : "张大仙", "age" : 19, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T09:38:16.820Z") }
{ "_id" : ObjectId("5fa27688b808fba58f5a3a42"), "name" : "李太白", "age" : 17, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T09:38:16.820Z") }

✏️ 查询一条记录

> db.student.findOne()
{
"_id" : ObjectId("5fa27688b808fba58f5a3a41"),
"name" : "张大仙",
"age" : 19,
"sdept" : "计算机系",
"sex" : "男",
"createdatetime" : ISODate("2020-11-04T09:38:16.820Z")
}


条件查询

✏️ 多个条件同时满足查询 $and

db.COLLECTION_NAME.find({K1:V1,K2:V2,K3:V3...})
或者
db.COLLECTION_NAME.find({$and:[{K1:V1},{K2:V2},{K3:V3}...]})

示例:

# 查询年龄为19,而且性别为男的学生
> db.student.find({age:19,sex:"男"})
{ "_id" : ObjectId("5fa27688b808fba58f5a3a41"), "name" : "张大仙", "age" : 19, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T09:38:16.820Z") }

> db.student.find({$and:[{age:19},{sex:"男"}]})
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4b"), "name" : "张大仙", "age" : 19, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }

✏️ 多个条件只是满足其中一个 $or

db.COLLECTION_NAME.find({$or:[{K1:V1},{K2:V2},{K3:V3}...]})

示例:

# 查询年龄是19或者为英语系的学生
> db.student.find({$or:[{age:19},{sdept:"英语系"}]})
{ "_id" : ObjectId("5fa27688b808fba58f5a3a41"), "name" : "张大仙", "age" : 19, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T09:38:16.820Z") }
{ "_id" : ObjectId("5fa27688b808fba58f5a3a43"), "name" : "黄花", "age" : 18, "sdept" : "英语系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T09:38:16.820Z") }

✏️ 根据数据类型来匹配对应的结果$type

db.COLLECTION_NAME.find({KEY:{$type:数字或者数据类型}})

​$tpye​​​操作符,​​MongoDB​​中可以使用的类型如下表所示:

类型

数字

备注

Double

1

String

2

Object

3

Array

4

Binary data

5

Undefined

6

已废弃

Object id

7

Boolean

8

Date

9

Null

10

Regular Expression

11

JavaScript

13

Symbol

14

JavaScript (with scope)

15

32-bit integer

16

Timestamp

17

64-bit integer

18

Min key

255

Query with -1

Max key

127

示例:

# 这里先插入一条数据进行测试
> db.student.insert({name:12,age:28,sdept:"体育系",createdatetime:new Date()})
WriteResult({ "nInserted" : 1 })

# 查询名字类型为Double类型的学生
> db.student.find({name:{$type:1}})
{ "_id" : ObjectId("5fa36936bde0f17be2c81931"), "name" : 12, "age" : 28, "sdept" : "体育系", "createdatetime" : ISODate("2020-11-05T02:53:42.760Z") }

✏️ 读取指定数量的数据记录limit()

db.COLLECTION_NAME.find().limit(NUMBER)

NUMBER:表示记录条数,默认值为20

示例:

# 查询性别为男学生前2条记录
> db.student.find({sex:"男"}).limit(1)
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4b"), "name" : "张大仙", "age" : 19, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }

✏️ 查询出来的记录,跳过指定数量的前多少条记录skip()

db.COLLECTION_NAME.find().skip(NUMBER)
或者
db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)

备注:skip(NUMBER)中的NUMBER默认值为0

示例:

# 查询所有的性别为男的学生信息并跳过第一条记录
> db.student.find({sex:"男"}).skip(1)
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4c"), "name" : "李太白", "age" : 17, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }

# 查询前两条性别为男的学生信息,跳过第一条记录
> db.student.find({sex:"男"}).limit(2).skip(1)
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4c"), "name" : "李太白", "age" : 17, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }

✏️ 对查询出来的记录进行排序 sort()

db.COLLECTION_NAME.find().sort({key:1})
或者
db.COLLECTION_NAME.find().sort({key:-1})

备注:sort()方法可以通过参数指定排序的字段,并使用1和-1来指定排序的方式,其中1为升序排列,而-1为降序排列。

示例:

# 查询所有学生信息,按照年龄升序排列
> db.student.find().sort({age:1})
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4c"), "name" : "李太白", "age" : 17, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4d"), "name" : "黄花", "age" : 18, "sdept" : "英语系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4b"), "name" : "张大仙", "age" : 19, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4e"), "name" : "菜花", "age" : 20, "sdept" : "数学系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa36936bde0f17be2c81931"), "name" : 12, "age" : 28, "sdept" : "体育系", "createdatetime" : ISODate("2020-11-05T02:53:42.760Z") }

# 查询所有学生信息,按照年龄降序排列
> db.student.find().sort({age:-1})
{ "_id" : ObjectId("5fa36936bde0f17be2c81931"), "name" : 12, "age" : 28, "sdept" : "体育系", "createdatetime" : ISODate("2020-11-05T02:53:42.760Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4e"), "name" : "菜花", "age" : 20, "sdept" : "数学系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4b"), "name" : "张大仙", "age" : 19, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4d"), "name" : "黄花", "age" : 18, "sdept" : "英语系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4c"), "name" : "李太白", "age" : 17, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }


比较查询

✏️ 大于查询 ​​$gt​

db.COLLECTION_NAME.find({KEY:{$gt:value}})

示例:

# 查询年龄大于17的学生
> db.student.find({age:{$gt:17}})
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4b"), "name" : "张大仙", "age" : 19, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4d"), "name" : "黄花", "age" : 18, "sdept" : "英语系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4e"), "name" : "菜花", "age" : 20, "sdept" : "数学系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }

✏️ 小于查询​​$lt​

db.COLLECTION_NAME.find({KEY:{$lt:value}})

示例:

# 查询年龄小于20的学生
> db.student.find({age:{$lt:20}})
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4b"), "name" : "张大仙", "age" : 19, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4c"), "name" : "李太白", "age" : 17, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4d"), "name" : "黄花", "age" : 18, "sdept" : "英语系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }

✏️ 大于等于查询 ​​$gte​

db.COLLECTION_NAME.find({KEY:{$gte:value}})

示例:

# 查询年龄大于等于17的学生
> db.student.find({age:{$gte:17}})
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4b"), "name" : "张大仙", "age" : 19, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4c"), "name" : "李太白", "age" : 17, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4d"), "name" : "黄花", "age" : 18, "sdept" : "英语系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4e"), "name" : "菜花", "age" : 20, "sdept" : "数学系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }

✏️ 小于等于查询 ​​$lte​

db.COLLECTION_NAME.find({KEY:{$lte:value}})

示例:

# 查询年龄小于等于20的学生
> db.student.find({age:{$lte:20}})
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4b"), "name" : "张大仙", "age" : 19, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4c"), "name" : "李太白", "age" : 17, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4d"), "name" : "黄花", "age" : 18, "sdept" : "英语系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4e"), "name" : "菜花", "age" : 20, "sdept" : "数学系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }

✏️ 不等于查询 ​​$ne​

db.COLLECTION_NAME.find({KEY:{$ne:value}})

示例:

# 查询年龄不等于20的学生
> db.student.find({age:{$ne:20}})
db.student.find({age:{$ne:20}})
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4b"), "name" : "张大仙", "age" : 19, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4c"), "name" : "李太白", "age" : 17, "sdept" : "计算机系", "sex" : "男", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4d"), "name" : "黄花", "age" : 18, "sdept" : "英语系", "sex" : "女", "createdatetime" : ISODate("2020-11-04T12:25:49.893Z") }

综合示例:

# 查询年龄在17~19之间的学生
> db.student.find({age:{$gt:17,$lt:19}})
# 查询年龄小于18,大于19的学生
> db.student.find({$or:[{age:{$lt:18}},{age:{$gt:19}}]})


查询已什么开头

格式如下:

db.COLLECTION_NAME.find({<key>:/^value/})

参数说明:
key:要查询的字段的名称
value:检查key字段的值中是否以value开始,格式:/^value/,斜杠“/”和“^”不能省略

示例:

rs0:PRIMARY> db.person.find({cid:/^512721/})
{ "_id" : ObjectId("5f0d09c4fc3df4986e62930c"), "cid" : "5127xxxxxx114702", "name" : "xxx", "createtime" : NumberLong(1594689988), "updatetime" : NumberLong(1604285711), "cid_type" : "10" }


查询某个字段总是否包含另一个值

格式如下:

db.COLLECTION_NAME.find({<key>:/value/})

参数说明:
key:要查询的字段的名称
value:查询key字段的值中是否包含着value的值,格式:/value/,前后的两个斜杠“/”不能省略

示例:

rs0:PRIMARY> db.person.find({name:/刘备/})
{ "_id" : ObjectId("5eb3e60ec158d2459d85aaab"), "cid" : "4208xxxx319", "name" : "刘备", "createtime" : NumberLong(1588848142), "updatetime" : NumberLong(1595218336), "cid_type" : "10" }
{ "_id" : ObjectId("5f1d4d75c158d2459d912d75"), "cid" : "4290xxxxx96", "name" : "刘备", "createtime" : NumberLong(1595755893), "updatetime" : NumberLong(1595755893), "cid_type" : "10" }
{ "_id" : ObjectId("5f0e542519c15a619088adf3"), "cid" : "510xxxxxx21", "name" : "徐刘备", "createtime" : NumberLong(1594774565), "updatetime" : NumberLong(1604016893), "cid_type" : "10" }


聚合查询


​MongoDB​​中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。


格式如下:

db.COLLECTION_NAME.aggregate([
{
管道:{聚合操作表达式}
}
])

管道:就是把找到的数据进行过滤的操作,常用的管道符如下表

管道符

描述

​$project​

修改输入文档的结构。可以用来重命名、增加或删除域

​$match​

用于过滤数据,只输出符合条件的文档。​​$match​​​使用​​MongoDB​​的标准查询操作

​$limit​

用来限制​​MongoDB​​聚合管道返回的文档数

​$skip​

在聚合管道中跳过指定数量的文档,并返回余下的文档

​$group​

将集合中的文档分组,可用于统计结果

​$sort​

将输入文档排序后输出

常用聚合表达式

表达式

描述

​$sum​

计算总和

​$avg​

计算平均值

​$min​

获取集合中所有文档对应值的最小值

​$max​

获取集合中所有文档对应值的最大值

✏️ 分组​​$group​

db.集合名字.aggregate([
{
$group:{_id:"$字段名",聚合函数的别名:{聚合表达式:"$字段名"}}
}
])

示例:

# 统计学生信息男生和女生的总年龄
> db.student.aggregate([
{
$group:{_id:"$sex",成绩总和:{$sum:"$age"}}
}
])

{ "_id" : "女", "成绩总和" : 38 }
{ "_id" : "男", "成绩总和" : 36 }


# 统计学生信息男生和女生各有多少人
> db.student.aggregate([
{
$group:{_id:"$sex",总人数:{$sum:1}}
}
])

{ "_id" : "女", "总人数" : 2 }
{ "_id" : "男", "总人数" : 2 }

//备注:$sum:1 等于MySQL的count(*) 统计总的记录数


# 求学生的总数和平均年龄
> db.student.aggregate([
{
$group:{_id:null,人数:{$sum:1},平均年龄:{$avg:"$age"}}
}
])

{ "_id" : null, "人数" : 4, "平均年龄" : 18.5 }


# 求男生或者女生的总数和平均年龄
> db.student.aggregate([
{
$group:{_id:"$sex",人数:{$sum:1},平均年龄:{$avg:"$age"}}
}
])
{ "_id" : "女", "人数" : 2, "平均年龄" : 19 }
{ "_id" : "男", "人数" : 2, "平均年龄" : 18 }


# 查询男生和女生的人数,按人数升序排列
> db.student.aggregate([
{
$group:{_id:"$sex",总人数:{$sum:1}}
},
{
$sort:{总人数:1}
}
])


# 查询年龄小于等19,只看两条记录
> db.student.find({age:{$lte:19}}).limit(2) #普通方法
# 管道的方法
> db.student.aggregate([
{
$match:{age:{$lte:19}}
},
{$limit:2}
])


# 查看男生的最大年龄
> db.student.aggregate([
{
$match:{sex:"男"}
},
{
$group:{_id:"$sex", 最高分:{$max:"$age"}}
}
])


# 修改文档结构,只含有_id,name,age
> db.student.aggregate([
{
$project:{name:1,age:1}
}
])
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4b"), "name" : "张大仙", "age" : 19 }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4c"), "name" : "李太白", "age" : 17 }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4d"), "name" : "黄花", "age" : 18 }
{ "_id" : ObjectId("5fa29dcd8b194ee77bc32b4e"), "name" : "菜花", "age" : 20 }
//备注:在$project,字段名:1 ---->获取该字段的所有内容
//等于MySQL中的 select name,age from student;


去重统计查询


根据指定字段进行去重,然后统计总数


> db.person.aggregate([
{"$group": {"_id": "$cid"}},
{"$group": {"_id": null, "counts": {"$sum": 1}}}
])

# 说明:
第一个group进行分组,中的"_id"指定需要去重的字段名称,这里根据cid进行去重
第二个group进行统计,中的"_id"可为空,也可为null


常用命令总结

# 选择切换数据库:
use DB_NAME

# 插入数据:
db.COLLECTION_NAME.insert({bson数据})

# 查询所有数据:
db.COLLECTION_NAME.find()

# 格式化显示查询的数据:
db.COLLECTION_NAME.find().pretty()

# 条件查询数据:
db.COLLECTION_NAME.find({K1:V1,K2:V2...})

# 查询符合条件的第一条记录:
db.COLLECTION_NAME.findOne({K1:V1,K2:V2...})

# 查询符合条件的前几条记录:
db.COLLECTION_NAME.find({K1:V1,K2:V2...}).limit(条数)

# 查询符合条件的跳过的记录:
db.COLLECTION_NAME.find({K1:V1,K2:V2...}).skip(条数)

# 查询满足多个条件中任意条件的记录:
db.COLLECTION_NAME.find({$or:[{K1:V1},{K2:V2},{K3:V3}...]})

# 对查询结果进行升序排序
db.COLLECTION_NAME.find().sort({kEY:1})

# 对查询结果进行降序排序
db.COLLECTION_NAME.find().sort({kEY:-1})

# 大于查询
db.COLLECTION_NAME.find({KEY:{$gt:value}})

# 小于查询
db.COLLECTION_NAME.find({KEY:{$lt:value}})

# 大于等于查询
db.COLLECTION_NAME.find({KEY:{$gte:value}})

# 小于等于查询
db.COLLECTION_NAME.find({KEY:{$lte:value}})

# 不等于查询
db.COLLECTION_NAME.find({KEY:{$ne:value}})

# 查询大于小于之间的数据记录
db.COLLECTION_NAME.find({KEY:{$gt:NUMBER,$lt:NUMBER}})

# 查询小于多少,或者大于多少的数据
db.COLLECTION_NAME.find({$or:[{KEY:{$lt:NUMBER}},{KEY:{$gt:NUMBER}}]})

# 统计查询
db.COLLECTION_NAME.find().count()

# 查询已什么开头
db.COLLECTION_NAME.find({<key>:/^value/})
或者:
db.COLLECTION_NAME.find({<key>: {"$regex": "^value"}})

# 查询某个字段总是否包含另一个值
db.COLLECTION_NAME.find({<key>:/value/})

# 根据指定字段去重并统计总数
db.person.aggregate([
{"$group": {"_id": "$cid"}},
{"$group": {"_id": null, "counts": {"$sum": 1}}}
])

人生是条无名的河,是浅是深都要过; 人生是杯无色的茶,是苦是甜都要喝; 人生是首无畏的歌,是高是低都要唱。




举报

相关推荐

0 条评论