MongoDB快速实战与基本原理

MongoDB快速实战与基本原理,第1张

MongoDB快速实战与基本原理

MongoDB快速实战与基本原理
  • MongoDB 基本概念详解
    • MongoDB的特点
    • 关系型数据库和文档型数据库主要概念对应
  • MongoDB 快速实战
    • MongoDB安装
    • 客户端使用——mongo shell
  • 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  ‐‐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查询对照表

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

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

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5612100.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-15
下一篇 2022-12-15

发表评论

登录后才能评论

评论列表(0条)

保存