Mongo 是 humongous 的中间部分,在英文里是“巨大无比”的意思。所以 MongoDB 可以翻译 成“巨大无比的数据库”,更优雅的叫法是“海量数据库”。Mongodb是一款非关系型数据库,说到非关系型数据库,区别于关系型数据库最显著的特征就是没有SQL语句,数据没有固定的数据类 型,关系数据库的所使用的SQL语句自从 IBM 发明出来以后,已经有 40 多年的历史了,但是时至今 日,开发程序员一般不太喜欢这个东西,因为它的基本理念和程序员编程的想法不一致。后来所谓的 NoSQL 风,指的就是那些不用 SQL 作为查询语言的数据存储系统,而文档数据库 MongoDB 正是 NoSQL 的代表
* | 关系型数据库 | 文档型数据库 |
---|---|---|
模型实体 | 表 | 集合 |
模型属性 | 列 | 字段 |
模型关系 | 表关联 | 内嵌数组,引用字段关联 |
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默认的数据存放路径
mongod # 如果你不希望使用的默认数据目录可以通过 添加 ‐‐dbpath 参数指定路径
或者从后台启动 需要指定 --logpath , 或者–syslog。并且需要实现创建好output文件。
mongod --logpath /data/db/logpath/output --fork
mongo shell, 用来操作MongoDB的javascript客户端界面
mongo ‐‐host <HOSTNAME> ‐‐port <PORT>
# 如果在本机使用的都是默认参数,也可以直接忽略所有参数
mongo
use admin # 设置密码需要切换到admin库
db.createUser(
{
user: "skq",
pwd: "123",
roles: [ "root" ]
}
)
show users # 查看所有用户信息
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
//writeConcern是安全级别 为可选字段
db.collection.insertOne( doc , { writeConcern: 安全级别} )
writeConcern 定义了本次文档创建操作的安全写级别
简单来说, 安全写级别用来判断一次数据库写入操作是否成功,安全写级别越高,丢失数据的风险就越低,然而写入操作的延迟也可能更高。 writeConcern 决定一个写操作落到多少个节点上才算成功。
writeConcern的取值包括
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();
db.inventory.find({$or:[{"qty":45},{"status":"A"}]}).pretty();
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 的区别
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}}} );
db.members.find({$and : [ {nickName:{ $eq : "曹操"}}, {points:{ $gt:500}}]});
当作用在不同的字段上时 可以省略 $and
当作用在同一个字段上面时可以简化为
db.members.find( {$or : [ {nickName:{ $eq : "刘备"}}, {points:{ $gt:1000}}]} )
db.members.find({points:{$exists:true}})
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:"军旅"}}})
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>})
定义了本次删除集合操作的安全写级别 这个指令不但删除集合内的所有文档,且删除集合的索引