nodejs操作mongodb增删改查

1. Mac系统上安装

使用Homebrew安装

$ brew updata // 更新Homebrew的package数据库
$ brew install mongodb

2. 启动MongoDB

$mongod --config /usr/local/etc/mongod.conf
// sudo mongod

3. 使用MongoDB shell

$ mongo

MongoDB是什么?

MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。 
特点是: 
高性能、易部署、易使用、存储数据方便

MongoDB概念

SQL MongoDB 解释
database database 数据库
table collection 数据库表/集合
row document 数据记录行/文档
column field 数据字段/域
index index 索引
table joins   表连接,MongoDB不支持
primary key primary key 主键,MongoDB自动将_id字段设置为主键

1. 数据库

  • 一个mongodb中可以建立多个数据库
  • MongoDB的默认数据库为“db”,该数据库存储在data目录中。
  • MongoDB的单个实例可以容纳多个独立的数据库,每一个都有自己的集合和权限,不同的数据库也放置在不同的文件中
show dbs 列出所有数据库
db //显式当前使用的数据库
use xxx 切换数据库

数据库的命名:通过标识符,使用utf8字符串

  • 非空
  • 不允许出现特殊字符$,/
  • 全部小写,最多64个字节
  • 有一些特殊保留数据库,如local、admin、config,命名时避免使用

2. 文档

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

3. 集合

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

结合的命名

  • 不能是空字符串
  • 不允许出现- 0
  • 不能以system.开头,这是系统保留的前缀
  • 不能包含保留字,$

4.MongoDB数据类型

类型 描述
null 用于表示空值或者不存在的字段{“x”,null}
布尔 ‘true’和’false’{“x”,true}
32位整数 Shell中这个类型不可用,MongoDB在控制台使用JS引擎进行输入,而JS仅支持64位浮点数,所以32位整数将会被自动转义
64位整数 Shell中这个类型不可用, 64位整数与32位整数一样,在MongoDB控制台使用时,会转义成64位浮点数
64位浮点数 Shell中的数字都是这种类型,下面是浮点数{“x”:3.14}、{“x”:3}
字符串 UTF-8字符串都可表示为字符串类型的数据{“x”:”foobar”}
符号 Shell不支持这种类型,将自动转义成字符串
对象ID 对象id是文档的12字节的唯一ID,时间戳
日期 日期类型存储的是从标准纪元开始的毫秒数{“x”:new Date()}
正则表达式 文档中可以包含正则表达式,其正则表达式采用JS语法来表示{“x”:/foobar/i}
代码 文档中可以包含js代码{“x”:function(){…}}
二进制数据 二进制数据可以由任意字节的串组成,不过Shell无法使用
最大值 BSON包括一个特殊类型,表示可能的最大值Shell无法使用
最小值 BSON包括一个特殊类型,表示可能的最小值Shell无法使用
未定义 文档中也可以使用未定义类型{“x”:undefined}
数组 值的集合或者列表可以表示成数组{“x”:[“a”,”b”,”c”]}
内嵌文档 文档可以包含别的文档{“x”:{“foo”:”bar”}}

MongoDB操作

1. 数据库常用命名

  1. Help查看提示命令 
    help 
    • db.help()
    • db.test.help()
    • db.test.find().help()
  2. 创建/切换数据库 
    • use music
  3. 查询数据库 
    • show dbs
  4. 查看当前使用的数据库 
    • db/db.getName()
  5. 显示当前DB状态 
    • db.stats()
  6. 查看当前DB版本 
    • db.version()
  7. 查看当前DB的链接机器地址 
    • db.getMongo()
  8. 删除数据库 
    • db.dropDatabase()

2. shell操作数据库

>  use music
switched to db music
>  show dbs // 当前列表里没有music数据库,因为没有数据
>  db.albums.insertOne({'title':'生命之花'})
{
    "acknowledged" : true,
    "insertedId" : ObjectId("591b158a71d7222a7a0d7f60")
}
> db.albums.find()
{ "_id" : ObjectId("591b158a71d7222a7a0d7f60"), "title" : "生命之花" }
> show dbs //插入数据后,有music数据库
music    0.000GB
> db
music
> db.getName()
music
> db.stats()
{
    "db" : "music",
    "collections" : 1,
    "views" : 0,
    "objects" : 1,
    "avgObjSize" : 46,
    "dataSize" : 46,
    "storageSize" : 16384,
    "numExtents" : 0,
    "indexes" : 1,
    "indexSize" : 16384,
    "ok" : 1
}
> db.version()
3.4.3
> db.getMongo()
connection to 127.0.0.1:27017
> db.dropDatabase() //删除数据库
{ "dropped" : "music", "ok" : 1 }

Collection 聚集集合操作

1. 创建一个聚集集合

db.createCollection(“collName”, {size: 20, capped: true, max: 100}); 
db.collName.isCapped(); //判断集合是否为定容量

> db.createCollection('albums',{size:20,capped:true,max:100})
{ "ok" : 1 }

capped:true 将集合固定大小,可以提高访问数据库的效率,插入数据时,会自动进行顺序管理

> db.albums.isCapped() //判断集合是否为定容量
true

size的优先级大于max

2. 得到指定名称的聚集集合

> db.getCollection('albums')
music.albums

3. 得到当前db的所有聚集集合

> db.getCollectionNames()
[ "albums" ]

4. 显示当前db所有聚集的状态

db.printCollectionStats()

添加、修改与删除集合数据

1. 添加

> db.albums.insertOne({title:'生命之花'})
> db.albums.insertMany([{title:'再见理想'},{title:'飞船'}])
> db.albums.insert([{title:'光辉岁月'},{title:'hello'}])
> db.albums.save({title:'21'})

2. 修改

修改所有数据


db.albums.updateMany(
  {},
  {
    $set:{artist:'adele'}
  }
  )
> db.albums.find()
{ "_id" : ObjectId("591b1d7871d7222a7a0d7f61"), "title" : "生命之花", "artist" : "adele" }
{ "_id" : ObjectId("591b1e0071d7222a7a0d7f62"), "title" : "再见理想", "artist" : "adele" }
{ "_id" : ObjectId("591b1e0071d7222a7a0d7f63"), "title" : "飞船", "artist" : "adele" }
{ "_id" : ObjectId("591b1eac71d7222a7a0d7f64"), "title" : "光辉岁月", "artist" : "adele" }
{ "_id" : ObjectId("591b1eac71d7222a7a0d7f65"), "title" : "hello", "artist" : "adele" }
{ "_id" : ObjectId("591b1ee971d7222a7a0d7f66"), "title" : "21", "artist" : "adele" }

修改一条数据

>db db.albums.updateMany(
  {title:'光辉岁月'},
  {
    $set:{artist:'Beyond'}
  }
  )
{ "_id" : ObjectId("591b1eac71d7222a7a0d7f64"), "title" : "光辉岁月", "artist" : "Beyond" }

3. 删除

删除一条记录

> db.albums.deleteOne({artist:'adele'})
{ "acknowledged" : true, "deletedCount" : 1 }
> db.albums.remove({artist:'adele'},true)
WriteResult({ "nRemoved" : 1 })

删除多条记录

> db.albums.deleteMany({artist:'adele'})
{ "acknowledged" : true, "deletedCount" : 3 }
> db.albums.remove({})
WriteResult({ "nRemoved" : 1 })

4. 查询修改删除

db.users.findAndModify({
    query: {age: {$gte: 25}}, 
    sort: {age: -1}, 
    update: {$set: {name: 'a2'}, $inc: {age: 2}},
    remove: true
});
db.runCommand({ findandmodify : "users", 
    query: {age: {$gte: 25}}, 
    sort: {age: -1}, 
    update: {$set: {name: 'a2'}, $inc: {age: 2}},
    remove: true
});
参数 详解 详解
query 查询过滤条件 {}
sort 如果多个文档符合查询过滤条件,将以该参数指定的排列方式选择出排在首位的对象,该对象将被操作 {}
remove 若为true,被选中对象将在返回前被删除 N/A
update 一个 修改器对象 N/A
new 若为true,将返回修改后的对象而不是原始对象。在删除操作中,该参数被忽略。 FALSE
upsert 创建新对象若查询结果为空 FALSE

聚集集合查询

1. 查询所有记录

db.userInfo.find(); 
相当于:select* from userInfo;

2.查询去重后数据

db.userInfo.distinct(“name”); 
相当于:select distict name from userInfo;

3. 查询age = 22的记录

db.userInfo.find({“age”: 22}); 
相当于: select * from userInfo where age = 22;

4. 查询age > 22的记录

db.userInfo.find({age: {$gt: 22}}); 
相当于:select * from userInfo where age >22;

5. 查询age < 22的记录

db.userInfo.find({age: {$lt: 22}}); 
相当于:select * from userInfo where age <22;

6. 查询age >= 25的记录

db.userInfo.find({age: {$gte: 25}}); 
相当于:select * from userInfo where age >= 25;

7. 查询age <= 25的记录

db.userInfo.find({age: {$lte: 25}});

8. 查询age >= 23 并且 age <= 26

db.userInfo.find({age: {gte:23,gte:23,lte: 26}}); 
查询name中包含 mongo的数据

9. db.userInfo.find({name: /mongo/});

//相当于%% 
select * from userInfo where name like ‘%mongo%’;

10. 查询name中以mongo开头的

db.userInfo.find({name: /^mongo/}); 
select * from userInfo where name like ‘mongo%’;

11. 查询指定列name、age数据

db.userInfo.find({}, {name: 1, age: 1}); // 只访问name和age两列的内容,1位标识 
相当于:select name, age from userInfo;

12. 查询指定列name、age数据, age > 25

db.userInfo.find({age: {$gt: 25}}, {name: 1, age: 1}); 
相当于:select name, age from userInfo where age >25;

13. 按照年龄排序

升序:db.userInfo.find().sort({age: 1}); // 1 为标识,升序 
降序:db.userInfo.find().sort({age: -1}); // -1 为标识,降序

14.查询name = zhangsan, age = 22的数据

db.userInfo.find({name: ‘zhangsan’, age: 22}); 
相当于:select * from userInfo where name = ‘zhangsan’ and age = ’22’;

15.查询前5条数据

db.userInfo.find().limit(5); 
相当于:select top 5 * from userInfo;

16. 查询10条以后的数据

db.userInfo.find().skip(10); 
相当于:select * from userInfo where id not in ( 
select top 10 * from userInfo 
);

17. 查询在5-10之间的数据

db.userInfo.find().limit(10).skip(5);

18. or与 查询

db.userInfo.find({$or: [{age: 22}, {age: 25}]}); 
相当于:select * from userInfo where age = 22 or age = 25;

19. 查询第一条数据

db.userInfo.findOne(); 
相当于:selecttop 1 * from userInfo; 
db.userInfo.find().limit(1);

20. 查询某个结果集的记录条数

db.userInfo.find({age: {$gte: 25}}).count(); 
相当于:select count(*) from userInfo where age >= 20;

21. 按照某列进行排序

db.userInfo.find({sex: {$exists: true}}).count(); 
相当于:select count(sex) from userInfo;

聚集集合查询shell 操作

https://api.douban.com/v2/movie/top250获取豆瓣电影数据 
将”subjects”:的数据插入到db.movie.insertMany()中,再写入到数据库

#

db.movie.find({year:'1994'},{title:1, year:1})
{ "_id" : ObjectId("591b296971d7222a7a0d7f67"), "title" : "肖申克的救赎", "year" : "1994" }
{ "_id" : ObjectId("591b296971d7222a7a0d7f68"), "title" : "这个杀手不太冷", "year" : "1994" }
{ "_id" : ObjectId("591b296971d7222a7a0d7f6a"), "title" : "阿甘正传", "year" : "1994" }

若不显示_id字段内容

> db.movie.find({year:'1994'},{title:1, year:1, _id:0})
{ "title" : "肖申克的救赎", "year" : "1994" }
{ "title" : "这个杀手不太冷", "year" : "1994" }
{ "title" : "阿甘正传", "year" : "1994" }

显式title,year和rating.averag

db.movie.find({},{title:1, year:1, 'rating.average':1, _id:0})
{ "rating" : { "average" : 9.6 }, "title" : "肖申克的救赎", "year" : "1994" }
{ "rating" : { "average" : 9.4 }, "title" : "这个杀手不太冷", "year" : "1994" }
{ "rating" : { "average" : 9.5 }, "title" : "霸王别姬", "year" : "1993" }
{ "rating" : { "average" : 9.4 }, "title" : "阿甘正传", "year" : "1994" }
{ "rating" : { "average" : 9.5 }, "title" : "美丽人生", "year" : "1997" }
{ "rating" : { "average" : 9.2 }, "title" : "千与千寻", "year" : "2001" }
{ "rating" : { "average" : 9.4 }, "title" : "辛德勒的名单", "year" : "1993" }
{ "rating" : { "average" : 9.2 }, "title" : "泰坦尼克号", "year" : "1997" }
{ "rating" : { "average" : 9.2 }, "title" : "盗梦空间", "year" : "2010" }
{ "rating" : { "average" : 9.3 }, "title" : "机器人总动员", "year" : "2008" }
{ "rating" : { "average" : 9.2 }, "title" : "海上钢琴师", "year" : "1998" }
{ "rating" : { "average" : 9.1 }, "title" : "三傻大闹宝莱坞", "year" : "2009" }
{ "rating" : { "average" : 9.2 }, "title" : "忠犬八公的故事", "year" : "2009" }
{ "rating" : { "average" : 9.2 }, "title" : "放牛班的春天", "year" : "2004" }
{ "rating" : { "average" : 9.2 }, "title" : "大话西游之大圣娶亲", "year" : "1995" }
{ "rating" : { "average" : 9.2 }, "title" : "教父", "year" : "1972" }
{ "rating" : { "average" : 9.1 }, "title" : "龙猫", "year" : "1988" }
{ "rating" : { "average" : 9 }, "title" : "楚门的世界", "year" : "1998" }
{ "rating" : { "average" : 9.2 }, "title" : "乱世佳人", "year" : "1939" }
{ "rating" : { "average" : 9.1 }, "title" : "天堂电影院", "year" : "1988" }

符合条件的条数

db.movie.find({},{title:1, year:1, 'rating.average':1, _id:0}).size()
20

limit 显式指定数目

> db.movie.find({},{title:1, year:1, 'rating.average':1, _id:0}).limit(5)
{ "rating" : { "average" : 9.6 }, "title" : "肖申克的救赎", "year" : "1994" }
{ "rating" : { "average" : 9.4 }, "title" : "这个杀手不太冷", "year" : "1994" }
{ "rating" : { "average" : 9.5 }, "title" : "霸王别姬", "year" : "1993" }
{ "rating" : { "average" : 9.4 }, "title" : "阿甘正传", "year" : "1994" }
{ "rating" : { "average" : 9.5 }, "title" : "美丽人生", "year" : "1997" }

skip 跳过制定数的数据

> db.movie.find({},{title:1, year:1, 'rating.average':1, _id:0}).skip(15)
{ "rating" : { "average" : 9.2 }, "title" : "教父", "year" : "1972" }
{ "rating" : { "average" : 9.1 }, "title" : "龙猫", "year" : "1988" }
{ "rating" : { "average" : 9 }, "title" : "楚门的世界", "year" : "1998" }
{ "rating" : { "average" : 9.2 }, "title" : "乱世佳人", "year" : "1939" }
{ "rating" : { "average" : 9.1 }, "title" : "天堂电影院", "year" : "1988" }

limit和skip 3-5条数据

> db.movie.find({},{title:1, year:1, 'rating.average':1, _id:0}).skip(2).limit(3)
{ "rating" : { "average" : 9.5 }, "title" : "霸王别姬", "year" : "1993" }
{ "rating" : { "average" : 9.4 }, "title" : "阿甘正传", "year" : "1994" }
{ "rating" : { "average" : 9.5 }, "title" : "美丽人生", "year" : "1997" }

sort 排序 1 为升序,-1为降序

> db.movie.find({},{title:1, year:1, 'rating.average':1, _id:0}).sort({'rating.average':1})

条件查询

> db.movie.find({'rating.average':{$gt:9.4}},{title:1, 'rating.average':1, _id:0})
{ "rating" : { "average" : 9.6 }, "title" : "肖申克的救赎" }
{ "rating" : { "average" : 9.5 }, "title" : "霸王别姬" }
{ "rating" : { "average" : 9.5 }, "title" : "美丽人生" }

按指定内容查询

> db.movie.find({genres:{$in:['犯罪']}},{title:1, genres:1, _id:0})
{ "genres" : [ "犯罪", "剧情" ], "title" : "肖申克的救赎" }
{ "genres" : [ "剧情", "动作", "犯罪" ], "title" : "这个杀手不太冷" }
{ "genres" : [ "剧情", "犯罪" ], "title" : "教父" }

node中使用MongoDB

var mongodb = require('mongodb')

// 创建数据库的连接

var server = new mongodb.Server(
  'localhost',
  27017,
  {auto_reconnect:true}
)

// 创建数据的连接
var db = new mongodb.Db(
  'movies',
  server,
  {safe: true}
)

// 测试数据库连接
db.open(function(err, db){
  if (err){
    console.log('log-'+ err)
  } else {
    console.log('log-connect mongodb success')
    db.collection('movie', {safe: true}, function(err, conn){
      if (err){
        console.log(err)
      } else {
        conn.find({}, {title:1, year:1, _id:0}).limit(3).skip(3).toArray(function(err, res){
          if(!err){
            res.forEach(function(value){
              console.log(value.title)
            })
          }
        })
      }
    })
  }
})
//打印结果
//阿甘正传
//美丽人生
//千与千寻

猜你喜欢

转载自blog.csdn.net/ZNYSYS520/article/details/81937284
今日推荐