MongoDB快速实战与基本原理

MongoDB 基本概念详解

Mongo 是 humongous 的中间部分,在英文里是“巨大无比”的意思。所以 MongoDB 可以翻译 成“巨大无比的数据库”,更优雅的叫法是“海量数据库”。Mongodb是一款非关系型数据库,说到非关系型数据库,区别于关系型数据库最显著的特征就是没有SQL语句,数据没有固定的数据类 型,关系数据库的所使用的SQL语句自从 IBM 发明出来以后,已经有 40 多年的历史了,但是时至今 日,开发程序员一般不太喜欢这个东西,因为它的基本理念和程序员编程的想法不一致。后来所谓的 NoSQL 风,指的就是那些不用 SQL 作为查询语言的数据存储系统,而文档数据库 MongoDB 正是 NoSQL 的代表

MongoDB的特点

  • MongoDB中的记录是一个文档,它是由字段和值对组成的数据结构。MongoDB文档类似于 JSON对象。字段的值可以包括其他文档,数组和文档数组。MongoDB数据模型和你的对象在内存 中的表现形式一样,一目了然的对象模型。
    在这里插入图片描述
    在这里插入图片描述
  • 同一个集合中可以包含不同字段(类型)的文档对象:同一个集合的字段可能不同
  • 线上修改数据模式,修改时应用与数据库都无须下线

关系型数据库和文档型数据库主要概念对应

* 关系型数据库 文档型数据库
模型实体 集合
模型属性 字段
模型关系 表关联 内嵌数组,引用字段关联

MongoDB 快速实战

MongoDB安装

  • 获取安装包并解压
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.4.10.tgz
tar ‐xvzf mongodb-linux-x86_64-rhel70-4.4.10.tgz

在这里插入图片描述

  • 配置环境变量
vi /etc/profile  

export MONGODB_HOME=/usr/local/mongo/mongodb-linux-x86_64-rhel70-4.4.10
export PATH=$PATH:$MONGODB_HOME/bin  

在这里插入图片描述

  • 创建数据目录
mkdir ‐p /data/db # 这个路径是MongoDB默认的数据存放路径
  • 启动MongoDB服务
mongod # 如果你不希望使用的默认数据目录可以通过 添加 ‐‐dbpath 参数指定路径

在这里插入图片描述

或者从后台启动 需要指定 --logpath , 或者–syslog。并且需要实现创建好output文件。

mongod --logpath /data/db/logpath/output --fork

在这里插入图片描述

客户端使用——mongo shell

mongo shell, 用来操作MongoDB的javascript客户端界面

  • 连接服务
mongo ‐‐host <HOSTNAME> ‐‐port <PORT> 
# 如果在本机使用的都是默认参数,也可以直接忽略所有参数
mongo
  • 设置密码
use admin # 设置密码需要切换到admin库
db.createUser( 
 { 
	 user: "skq", 
	 pwd: "123",
	 roles: [ "root" ] 
 } 
)
show users # 查看所有用户信息

在这里插入图片描述

  • 停服务,exit 退出 mongo
db.shutdownServer() # 停掉服务

在这里插入图片描述

  • 以授权模式启动并连接
    此处有问题,暂时无法按照下列指令连接成功
mongod ‐‐auth
mongo ‐u skq

MongoDB基于安全性考虑,默认安装后只会绑定本地回环 IP 127.0.0.1, 可以通过启动服务时,指定 绑定的IP 如 只允许通过 IP: 192.168.1.104 访问,
mongod ‐‐bind_ip 192.168.1.104
连接用以下指令
mongo ‐host 192.168.1.104 ‐u skq

MongoDB 核心操作与原理详解

创建数据库,集合,文档

//writeConcern是安全级别 为可选字段  
db.collection.insertOne(  doc ,  {
    
      writeConcern: 安全级别} )

writeConcern 定义了本次文档创建操作的安全写级别
简单来说, 安全写级别用来判断一次数据库写入操作是否成功,安全写级别越高,丢失数据的风险就越低,然而写入操作的延迟也可能更高。 writeConcern 决定一个写操作落到多少个节点上才算成功。

writeConcern的取值包括

  • 0: 发起写操作,不关心是否成功
  • 1 集群中最大数据节点数: 写操作需要被复制到指定节点数才算成功
  • majority: 写操作需要被复制到大多数节点上才算成功,发起写操作的程序将阻塞到写操作到达指定的节点数为止
use demo

db.members.insertOne({
    
    "name":"zhangsan",age:19});

在这里插入图片描述
在这里插入图片描述

show tables
show collections
db.members.find();
db.members.insertOne({
    
    "_id":1,"name":"zhangsan",age:19});

插入文档时,如果没有显示指定主键,MongoDB将默认创建一个主键,字段固定为_id,ObjectId() 可以快速生成的12字节id 作为主键,ObjectId 前四个字节代表了主键生成的时间,精确到秒。主键 ID在客户端驱动生成,一定程度上代表了顺序性,但不保证顺序性, 可以通过ObjectId(“id值”).getTimestamp() 获取创建时间。
在这里插入图片描述
在这里插入图片描述

db.members.insertMany([{
    
    "_id":100,"name":"lisi",age:19},{
    
    "_id":100,"name":"lisi2",age:19},{
    
    "_id":101,                                                        "name":"lisi3",age:19}],{
    
    "ordered":true});

在这里插入图片描述
在这里插入图片描述

db.members.insertMany([{
    
    "_id":100,"name":"lisi",age:19},{
    
    "_id":100,"name":"lisi2",age:19},{
    
    "_id":101,                                                        "name":"lisi3",age:19}],{
    
    "ordered":false});

在这里插入图片描述
ordered: 是否按顺序进行写入 顺序写入时,一旦遇到错误,便会退出,剩余的文档无论正确与否,都不会写入 乱序写入,则只要文档可以正确写入就会正确写入,不管前面的文档是否是错误的文档

db.inventory.insertMany([  {
    
     item: "journal", qty: 25, status: "A", size: {
    
     h: 14, w: 21, uom: "cm" }, tags: [ "blank", "red" ] },  {
    
     item: "notebook", qty: 50, status: "A", size: {
    
     h: 8.5, w: 11, uom: "in" }, tags: [ "red", "blank" ] },  {
    
     item: "paper", qty: 10, status: "D", size: {
    
     h: 8.5, w: 11, uom: "in" }, tags: [ "red", "blank", "plain" ] },  {
    
     item: "planner", qty: 0, status: "D", size: {
    
     h: 22.85, w: 30, uom: "cm" }, tags: [ "blank", "red" ] },  {
    
     item: "postcard", qty: 45, status: "A", size: {
    
     h: 10, w: 15.25, uom: "cm" }, tags: [ "blue" ] }  ]);

db.inventory.find();
db.inventory.find().pretty();

MongoDB以集合(collection)的形式组织数据,collection 相当于关系型数据库中的表,如果 collection不存在,当你对不存在的collection进行操作时,将会自动创建一个collection 如下
在这里插入图片描述
在这里插入图片描述

条件查询:

db.inventory.find({
    
    "_id" : ObjectId("61a1b1061df00200ed561724")}).pretty();

精准等值查询
在这里插入图片描述

db.inventory.find({
    
    "qty" : 45,"status" : "A"}).pretty();

多条件查询
在这里插入图片描述

db.inventory.find( {
    
     "size.uom": "in" } );

嵌套对象精准查询
在这里插入图片描述

db.inventory.find( {
    
     }, {
    
     item: 1, status: 1 } );

返回指定字段
默认会返回_id 字段, 同样可以通过指定 _id:0 ,不返回_id 字段
在这里插入图片描述

db.inventory.find({
    
    $and:[{
    
    "qty":45},{
    
    "status":"A"}]}).pretty();

条件查询 and
在这里插入图片描述

db.inventory.find({
    
    $or:[{
    
    "qty":45},{
    
    "status":"A"}]}).pretty();

条件查询 or
在这里插入图片描述

Mongo查询条件和SQL查询对照表

SQL MQL
a<>1 或者 a!=1 { a : {$ne: 1}}
a>1 { a: {$gt:1}}
a>=1 { a: {$gte:1}}
a<1 { a: {$lt:1}}
a<=1 { a: { $lte:1}}
in { a: { $in:[ x, y, z]}}
not in { a: { $nin:[ x, y, z]}}
a is null { a: { $exists: false }}

insertOne, inertMany, insert 的区别

  • insertOne, 和 insertMany命令不支持 explain命令
  • insert支持 explain命令

复合主键

db.product.insertOne({
    
    _id:{
    
    "product_name":"苹果","product_type":"6s"},create_time:new Date()})

在这里插入图片描述
在这里插入图片描述
注意复合主键,字段顺序换了,会当做不同的对象被创建,即使内容完全一致

逻辑操作符匹配

$not : 匹配筛选条件不成立的文档
$and : 匹配多个筛选条件同时满足的文档
$or : 匹配至少一个筛选条件成立的文档
$nor : 匹配多个筛选条件全部不满足的文档

 db.members.insertMany([ {
    
     nickName:"曹操", points:1000 },{
    
     nickName:"刘备", points:500 }])

在这里插入图片描述

db.members.find({
    
    points: {
    
     $not: {
    
     $lt: 100}}} );

$not 也会筛选出并不包含查询字段的文档
在这里插入图片描述

db.members.find({
    
    $and : [ {
    
    nickName:{
    
     $eq : "曹操"}}, {
    
    points:{
    
     $gt:500}}]});

在这里插入图片描述
当作用在不同的字段上时 可以省略 $and
在这里插入图片描述
当作用在同一个字段上面时可以简化为
在这里插入图片描述

db.members.find(  {
    
    $or : [  {
    
    nickName:{
    
     $eq : "刘备"}},  {
    
    points:{
    
     $gt:1000}}]}  )

如果都是等值查询的话, $or 和 $in 结果是一样的
在这里插入图片描述

字段匹配

db.members.find({
    
    points:{
    
    $exists:true}})

$exists:匹配包含查询字段的文档
在这里插入图片描述

db.members.count();
db.members.find().skip(1).count(true);

默认情况下 , 这里的count不会考虑 skip 和 limit的效果,如果希望考虑 limit 和 skip ,需要设置 为 true。 分布式环境下,count 不保证数据的绝对正确
在这里插入图片描述

db.members.find().sort({
    
    ponints:1})

1 表示由小到大, -1 表示逆向排序
当同时应用 sort, skip, limit 时 ,应用的顺序为 sort, skip, limit
在这里插入图片描述

db.movies.insertMany([{
    
    name:"战狼",tag:["动作","军旅","热血"]}])

db.movies.find({
    
    },{
    
    _id:0,tag:{
    
    $slice:1}})

文档投影: 可以有选择性的返回数据
投影设置:{ field: < 1 :1 表示需要返回, 0: 表示不需要返回 , 只能为 0,或者1 , 非主键字 段,不能同时混选0 或 1>}

$slice 返回数组中的部分元素
slice:
1: 数组第一个元素
-1:最后一个元素
-2:最后两个元素
slice[ 1,2 ] : skip, limit 对应的关系
在这里插入图片描述
在这里插入图片描述

db.movies.find({
    
    },{
    
    _id:0,name:1,tag:{
    
    $elemMatch:{
    
    $eq:"军旅"}}})

还可以使用 elementMatch 进行数组元素进行匹配
在这里插入图片描述

更新操作

updateOne/updateMany 方法要求更新条件部分必须具有以下之一,否则将报错
$set 给符合条件的文档新增一个字段,有该字段则修改其值
$unset 给符合条件的文档,删除一个字段
$push: 增加一个对象到数组底部
$pop:从数组底部删除一个对象
$pull:如果匹配指定的值,从数组中删除相应的对象
$pullAll:如果匹配任意的值,从数据中删除相应的对象
$addToSet:如果不存在则增加一个值到数组

db.userInfo.insert([  {
    
     name:"zhansan",  tag:["90","Programmer","PhotoGrapher"]  },  {
    
     name:"lisi",  tag:["90","Accountant","PhotoGrapher"]  }]);

db.userInfo.updateMany(  {
    
    tag:"90"},  {
    
    $set:{
    
    flag:1}}  );

在这里插入图片描述

db.userInfo.find( {
    
    $or: [{
    
    tag:"Accountant"}, {
    
    tag:"Programmer"} ] });

在这里插入图片描述

db.userInfo.updateMany(  {
    
    tag:"90"},  {
    
    $unset:{
    
    flag:1}}  );

在这里插入图片描述

db.userInfo.updateOne(  {
    
    name:"lisi"},  {
    
    $inc:{
    
    age:-1}}  );

在这里插入图片描述

db.userInfo.updateOne(  {
    
    name:"lisi"},  {
    
    $mul:{
    
    age:10}}  );

在这里插入图片描述

删除文档

db.userInfo.remove({
    
    name:"lisi"},{
    
    justOne:true})

默认情况下,会删除所有满足条件的文档, 可以设定参数 { justOne:true},只会删除满足添加的第一 条文档
在这里插入图片描述

删除集合

db.collection.remove 只会删除所有的文档,直接使用remve删除所有文档效率比较低,可以使用 drop 删除集合,才重新创建集合以及索引

db.collection.drop( {
    
     writeConcern:<doc>})

定义了本次删除集合操作的安全写级别 这个指令不但删除集合内的所有文档,且删除集合的索引

猜你喜欢

转载自blog.csdn.net/yemuxiaweiliang/article/details/121557153