MongoDB

1. 什么是MongoDB?

MongoDB是一个开源NoSQL(NotOnly SQL)分布式数据库,不同于MySQL的关系型数据库。它所有的数据以文档(Binary JSON文档)的形式存储。没有表和行的概念。

1. 基本概念

数据库(database):一个Mongo实例对应多个数据库。

     Mongo中的数据库等同于MySql中的数据库。

集合(collection): 数据库由集合组成。

    Mongo中的集合等同于MySql中的表(table)。

文档(document):集合由文档组成。

   Mongo中的文档等同于MySql中的记录(row)。

key: 文档由key-value组成。

   Mongo中的key相当于MySql中的列(field)。

2. 优缺点

优点:

1) 高并发

2)大数据量

3)分布式(多台服务器)

缺点:

不可靠,会出现数据丢失

3. ObjectId

在MySql数据库中,id是自增ID。在MongoDB这种分布式数据库中,该方法不实用; 在该数据库中,使用12个字节字符串组成的ObjectId类型。

  • 4字节: UNIX时间戳
  • 3字节:运行MongoDB数据库的机器的MAC地址
  • 2字节:生成该Id的进程
  • 3字节:随机数

2. MongoDB的安装

1. windows系统

下载安装包,解压,打开bin目录

cd MongoDB/bin

启动服务器端(默认断开27017)

//  data是数据存放目录
mongod --dbpath=./data

mongod命令的其他参数:

--port 指定端口号;默认端口是27017
--logpath 指定日志文件;不是文件目录
--logappend 使用追加的方式追加日志
--dbpath 指定数据库路径
--directoryperdb 设置每个数据库在单独的目录

监听客户端请求

mongo
// 成功的标志是出现>

2. MacOS系统

安装教程

brew tap mongodb/brew
// $ brew install <formula>
eg: brew install mongodb-community

监听客户端请求

mongo

安装后的文件夹所在的目录

/usr/local/Cellar/mongodb-community/

3. MongoDB的命令

查看mongoDB的所有命令:

db.help();

1. 操作数据库

1. 创建数据库

使用use,切换到对应的数据库。如果数据库不存在,则创建数据库

use dbname;

2. 查看数据库列表

show dbs;

3. 删除数据库

先切换到数据库;再删除

use dbname;
db.dropDatabase();

2. 操作集合

1.创建集合

切换到要操作的数据库,直接插入数据;会自动创建集合;其中stu是集合。

use school;
db.stu.insert({name: "lyra"});
db.stu.insert({_id: 1, name: "lyra1"});

2. 创建集合2

db.createCollection('stu')

3. 操作文档

1. 插入文档

插入多条数据

> db.stu.find();
{ "_id" : 1, "name" : "lyraLee", "hobbies" : [ "drawing", "drinking", "smoking" ] }
> db.stu.insert([{_id:2, age:2}, {_id: 3, age: 3}])
BulkWriteResult({
    "writeErrors" : [ ],
    "writeConcernErrors" : [ ],
    "nInserted" : 2,
    "nUpserted" : 0,
    "nMatched" : 0,
    "nModified" : 0,
    "nRemoved" : 0,
    "upserted" : [ ]
})
> db.stu.find();
{ "_id" : 1, "name" : "lyraLee", "hobbies" : [ "drawing", "drinking", "smoking" ] }
{ "_id" : 2, "age" : 2 }
{ "_id" : 3, "age" : 3 }

2. 更新文档(整条内容替换)

db.stu.save({_id: 1, name: "lyra1"});

3. 查看集合下所有文档内容

db.stu.find();

查看指定的文档

db.stu.find(<query>);

4. 删除集合

db.stu.drop();

4. 更新文档

  • query:  查询条件; 如果是{}, 则表示更新所有的数据。
  • updateObj: 更新体
  • upsert: update/insert; 为true时表示,查询条件匹配则更新;不匹配则插入
  • multi: 为true时表示同时变更所有的数据
db.collection.update(
<query>,
<updateObj>, {
upsert: true, multi: true } }

eg:

> db.stu.find();
{ "_id" : 1, "name" : "lyraLee" }
> db.stu.update({_id: 2}, {age: 1})
WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })
> db.stu.update({_id: 2}, {age: 1}, {upsert: true})
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : 2 })
> db.stu.find();
{ "_id" : 1, "name" : "lyraLee" }
{ "_id" : 2, "age" : 1 }

5. 更新(update)操作符

1. $set- 只修改指定字段,其他字段保持不变

> db.stu.find({_id:1});
{ "_id" : 1, "name" : "lyraLee", "age" : 1 }
> db.stu.update({_id: 1}, {$set:{age: 18}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.stu.find({_id:1});
{ "_id" : 1, "name" : "lyraLee", "age" : 18 }

2. $inc-执行字段增加

> db.stu.find({_id:1});
{ "_id" : 1, "name" : "lyraLee", "age" : 18 }
> db.stu.update({_id: 1}, {$inc:{age: 1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.stu.find({_id:1});
{ "_id" : 1, "name" : "lyraLee", "age" : 19 }

3. $unset-删除指定字段

> db.stu.find({_id:1});
{ "_id" : 1, "name" : "lyraLee", "age" : 19 }
> db.stu.update({_id: 1}, {$unset:{age: 1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.stu.find({_id:1});
{ "_id" : 1, "name" : "lyraLee" }

4. $push-添加数组数据(数据数据可能会重复)

> db.stu.find({_id:1});
{ "_id" : 1, "name" : "lyraLee" }
> db.stu.update({_id:1}, {$push:{hobbies:'swimming'}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.stu.find({_id:1});
{ "_id" : 1, "name" : "lyraLee", "hobbies" : [ "swimming" ] }
> db.stu.update({_id:1}, {$push:{hobbies:'swimming'}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.stu.find({_id:1});
{ "_id" : 1, "name" : "lyraLee", "hobbies" : [ "swimming", "swimming" ] }

5. $ne-NotEqual限制数组的重复添加

> db.stu.find({_id:1});
{ "_id" : 1, "name" : "lyraLee", "hobbies" : [ "swimming" ] }
> db.stu.update({_id:1, hobbies:{$ne: 'swimming'}}, {$push:{hobbies:'swimming'}});
WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })
> db.stu.find({_id:1});
{ "_id" : 1, "name" : "lyraLee", "hobbies" : [ "swimming" ] }

6.$addToSet-添加不重复数据的数组(集合)

> db.stu.find({_id:1});
{ "_id" : 1, "name" : "lyraLee", "hobbies" : [ "swimming" ] }
> db.stu.update({_id:1}, {$addToSet:{hobbies:'swimming'}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
> db.stu.find({_id:1});
{ "_id" : 1, "name" : "lyraLee", "hobbies" : [ "swimming" ] }
> db.stu.update({_id:1}, {$addToSet:{hobbies:'singing'}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.stu.find({_id:1});
{ "_id" : 1, "name" : "lyraLee", "hobbies" : [ "swimming", "singing" ] }

7. $pop-删除数组的最后一个数

> db.stu.find({_id:1});
{ "_id" : 1, "name" : "lyraLee", "hobbies" : [ "swimming", "singing" ] }
> db.stu.update({_id:1}, {$pop:{hobbies:1}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
>
> db.stu.find({_id:1});
{ "_id" : 1, "name" : "lyraLee", "hobbies" : [ "swimming" ] }

8.$each-合并数组元素

> db.stu.find({_id:1});
{ "_id" : 1, "name" : "lyraLee", "hobbies" : [ "swimming" ] }
> var arr = ['drinking', 'smoking'];
> db.stu.update({_id:1}, {$addToSet:{hobbies:{$each: arr}}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.stu.find({_id:1});
{ "_id" : 1, "name" : "lyraLee", "hobbies" : [ "swimming", "drinking", "smoking" ] }

9. 修改指定索引的值

> db.stu.find({_id:1});
{ "_id" : 1, "name" : "lyraLee", "hobbies" : [ "swimming", "drinking", "smoking" ] }
> db.stu.update({_id:1}, {$set:{'hobbies.0': 'drawing'}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.stu.find({_id:1});
{ "_id" : 1, "name" : "lyraLee", "hobbies" : [ "drawing", "drinking", "smoking" ] }

6. 删除文档

基本语法:

  • collection_name 集合名称
db.collection_name.remove(
   <query>,
   {
      justOne: <boolean>
   }
)

删除所有匹配条件的数据

> db.stu.find();
{ "_id" : 1, "name" : "lyraLee", "hobbies" : [ "drawing", "drinking", "smoking" ] }
{ "_id" : 2, "age" : 1 }
> db.stu.remove({age: 1})
WriteResult({ "nRemoved" : 1 })
> db.stu.find();
{ "_id" : 1, "name" : "lyraLee", "hobbies" : [ "drawing", "drinking", "smoking" ] }

justOne只删除匹配条件的第一条数据

> db.stu.find();
{ "_id" : 1, "name" : "lyraLee", "hobbies" : [ "drawing", "drinking", "smoking" ] }
{ "_id" : 2, "age" : 2 }
{ "_id" : 3, "age" : 2 }
> db.stu.remove({age:2}, {justOne: true})
WriteResult({ "nRemoved" : 1 })
> db.stu.find();
{ "_id" : 1, "name" : "lyraLee", "hobbies" : [ "drawing", "drinking", "smoking" ] }
{ "_id" : 3, "age" : 2 }

7. 查询文档操作符

1. find-查询出所有满足条件的数据(最多20条)

基本语法

  • collection_name: 集合名称
  • query: 查询条件
  • key: 指定特定的列
  • 0: exclusion 不包含该列
  • 1: inclusion; 包含该列
db.collection_name.find(
  <query>,
  {
     key: 0/1
  }
)

⚠️: 0/1不能混用;即不能同时存在(_id除外)

示例: 返回指定的列

> db.stu.find();
{ "_id" : 1, "name" : "lyraLee", "hobbies" : [ "drawing", "drinking", "smoking" ] }
{ "_id" : 3, "age" : 2 }
> db.stu.find({_id:1}, {name:1, _id:0});
{ "name" : "lyraLee" }

2. findone-查询出满足条件的第一条数据

> db.stu.find();
{ "_id" : 1, "name" : "lyraLee", "hobbies" : [ "drawing", "drinking", "smoking" ] }
{ "_id" : 3, "age" : 2 }
{ "_id" : ObjectId("5e4ca86e925de31003f5cfbe"), "sex" : "female" }
{ "_id" : ObjectId("5e4ca885925de31003f5cfbf"), "sex" : "female" }
> db.stu.findOne({sex: 'female'})
{ "_id" : ObjectId("5e4ca86e925de31003f5cfbe"), "sex" : "female" }

3. $in- 包含

> db.stu.find();
{ "_id" : 1, "age" : 1 }
{ "_id" : 2, "age" : 2 }
{ "_id" : 3, "age" : 3 }
{ "_id" : 4, "age" : 4 }
{ "_id" : 5, "age" : 5 }
> db.stu.find({age: {$in: [2,4]}})
{ "_id" : 2, "age" : 2 }
{ "_id" : 4, "age" : 4 }

4. $nin- 不包含

> db.stu.find({age: {$nin: [2,4]}})
{ "_id" : 1, "age" : 1 }
{ "_id" : 3, "age" : 3 }
{ "_id" : 5, "age" : 5 }

5. $gte - greater than Or equal

   $lte - less than Or equal

   $lt - less than

   $gt - greater than

> db.stu.find({age: {$gte: 2, $lte: 4}})
{ "_id" : 2, "age" : 2 }
{ "_id" : 3, "age" : 3 }
{ "_id" : 4, "age" : 4 }

6. $not - 取反

> db.stu.find({age:{$not: {$gte: 2, $lte: 4}}})
{ "_id" : 1, "age" : 1 }
{ "_id" : 5, "age" : 5 }

7. 查询数组

  • 包含数组中的某一个值
> db.stu.find()
{ "_id" : 1, "age" : 1, "hobbies" : [ "A", "B", "C" ] }
{ "_id" : 2, "age" : 2, "hobbies" : [ "A" ] }
{ "_id" : 3, "age" : 3, "hobbies" : [ "B" ] }
{ "_id" : 4, "age" : 4, "hobbies" : [ "A", "B" ] }
{ "_id" : 5, "age" : 5, "hobbies" : [ "C" ] }
> db.stu.find({hobbies: 'A'})
{ "_id" : 1, "age" : 1, "hobbies" : [ "A", "B", "C" ] }
{ "_id" : 2, "age" : 2, "hobbies" : [ "A" ] }
{ "_id" : 4, "age" : 4, "hobbies" : [ "A", "B" ] }
  • $all-同时包含数组中的某些值
> db.stu.find({hobbies: {$all: ['A','B']}})
{ "_id" : 1, "age" : 1, "hobbies" : [ "A", "B", "C" ] }
{ "_id" : 4, "age" : 4, "hobbies" : [ "A", "B" ] }
  • $in-包含其中任意一个值
> db.stu.find({hobbies: {$in: ['A','B']}})
{ "_id" : 1, "age" : 1, "hobbies" : [ "A", "B", "C" ] }
{ "_id" : 2, "age" : 2, "hobbies" : [ "A" ] }
{ "_id" : 3, "age" : 3, "hobbies" : [ "B" ] }
{ "_id" : 4, "age" : 4, "hobbies" : [ "A", "B" ] }
  • $size-按数组长度查询
> db.stu.find({hobbies: {$size:2}})
{ "_id" : 4, "age" : 4, "hobbies" : [ "A", "B" ] }
  • $slice-返回数组的部分数据
> db.stu.find({_id:1}, {hobbies: {$slice: 2}})
{ "_id" : 1, "age" : 1, "hobbies" : [ "A", "B" ] }
> db.stu.find({_id:1}, {hobbies: {$slice: -2}})
{ "_id" : 1, "age" : 1, "hobbies" : [ "B", "C" ] }

8. $where-查询条件语句(查询速度慢)

> db.stu.find({$where: "this.age>2 && this.age<4"})
{ "_id" : 3, "age" : 3, "hobbies" : [ "B" ] }

8. 查询方法

1. cursor

find()方法返回一个结果集(最多返回20条),可以通过其逐条查询

- cursor.hasNext():返回布尔值

- cursor.next(): 下一条数据

- printjson(data): 打印数据 

> var cursor = db.stu.find();
> while(cursor.hasNext()) { printjson(cursor.next()); }
{ "_id" : 1, "age" : 1, "hobbies" : [ "A", "B", "C" ] }
{ "_id" : 2, "age" : 2, "hobbies" : [ "A" ] }
{ "_id" : 3, "age" : 3, "hobbies" : [ "B" ] }
{ "_id" : 4, "age" : 4, "hobbies" : [ "A", "B" ] }
{ "_id" : 5, "age" : 5, "hobbies" : [ "C" ] }

2. count()

返回结果集的条数

> db.stu.count();
30

3. 正则表达式查询

> db.stu.find({name: /^my/})
{ "_id" : 1, "name" : "mynameishehe" }

4. 逻辑与或(and/or)

-and

> db.stu.find({age: {$gte: 2, $lte: 4}})
{ "_id" : 2, "age" : 2 }
{ "_id" : 3, "age" : 3 }
{ "_id" : 4, "age" : 4 }

-$or

> db.stu.find({$or: [{_id: {$lte: 2}}, {_id: {$gte: 4} }]})
{ "_id" : 1, "name" : "mynameishehe" }
{ "_id" : 2, "age" : 2, "hobbies" : [ "A" ] }
{ "_id" : 4, "age" : 4, "hobbies" : [ "A", "B" ] }
{ "_id" : 5, "age" : 5, "hobbies" : [ "C" ] }

5. 分页查询

skip()-  跳过的数据条数;即(pageNum-1)*pageSize

limit(num)- 限制返回的数据条数; 即pageSize

sort({key: 1/-1})- 按照key排序;其中1表示正序;-1表示倒序

/**示例:返回排序后的第二页(pageSize=3)**/
> db.stu.find();
{ "_id" : 1, "age" : 1 }
{ "_id" : 2, "age" : 2 }
{ "_id" : 3, "age" : 3 }
{ "_id" : 4, "age" : 4 }
{ "_id" : 5, "age" : 5 }
{ "_id" : 6, "age" : 6 }
/**按照age字段正序排序后取第二页**/
> db.stu.find().skip((2-1)*3).limit(3).sort({age:1})
{ "_id" : 4, "age" : 4 }
{ "_id" : 5, "age" : 5 }
{ "_id" : 6, "age" : 6 }
/**按照age字段倒序排序后取第二页,**/
> db.stu.find().sort({age: -1}).skip((2-1)*3).limit(3)
{ "_id" : 3, "age" : 3 }
{ "_id" : 2, "age" : 2 }
{ "_id" : 1, "age" : 1 }

4. MongoDB数据库的备份和恢复

mongo/mongodump/mongorestore都是全局命令

1. 备份

/**备份后的文件位于命令运行时所在文件夹下***/
$ mongodump --out './bk' --collection stu --db test

2. 从备份的数据恢复

$ mongorestore './bk'

5. 执行脚本

mongo 文件名

示例:脚本内容-insert.js

var start = Date.now();
var users = [];
for(let i=0; i<10000; i++) {
  users.push({_id: i, name: 'lyra'+i, age: i});
}
db.stu.insert(users); /**批量插入;提高效率 **/
var cost = Date.now() - start;
print(cost + 'ms');

运行脚本

$ mongo insert.js
MongoDB shell version v4.2.3
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("0587a441-5c94-4166-8634-4e1e2ea3c8cd") }
MongoDB server version: 4.2.3
35ms
原文地址:https://www.cnblogs.com/lyraLee/p/12333140.html