前端培训-中级阶段(51)- nodeJS操作MongoDB、文档CURD操作

linong

前端最基础的就是 HTML+CSS+Javascript。掌握了这三门技术就算入门,但也仅仅是入门,现在前端开发的定义已经远远不止这些。前端小课堂(HTML/CSS/JS),本着提升技术水平,打牢基础知识的中心思想,我们开课啦(每周四)。

使用命令操作 MongoDB 数据库

image.png

数据库操作

  1. 显示所有数据库
    show dbs
  2. 切换数据库
    use <DATABASE_NAME>。比如说我们切换到 admin 数据库 use admin
    如果数据库不存在,则创建数据库。如果数据库存在,则切换到指定数据库。
  3. 显示当前操作的数据库
    db
  4. 显示当前数据库下的所有表
    show collections
  5. 删除当前数据库,这种危险命令还是不要学了
    db.dropDatabase()

数据操作

因为没有表的概念(集合),也不要求字段一致(文档)。所以我们直接快乐的操作数据就好了。

操作命令为 db.<collection>.<>,比如我们查 user 表的记录 db.user.find()

也可以使用 tab 来自动补全。

image.png

insert 插入操作

注意: 在 MongoDB 中,集合只有在内容插入后才会创建! 就是说,创建集合(数据表)后要再插入一个文档(记录),集合才会真正创建。(db.createCollection(name, options) 这种创建命令不会也罢,当然如果你需要定制 options 还是需要使用的

  1. 插入一个文档,如果主键重复则报错。
    db.<collection>.insert(document)
  2. 插入一个文档,如果主键重复则报错。(3.2+ 新增)
    db.<collection>.insertOne(document)

    db.collection.insertOne(
       <document>,
       {
          writeConcern: <document>
       }
    )

    参数说明:

    • document:要写入的文档。
    • writeConcern:写入策略,默认为 1,即要求确认写操作,0 是不要求。
  3. 插入多个文档,如果主键重复则报错。(3.2+ 新增)
    db.<collection>.insertMany([document1,document2])

    db.collection.insertMany(
       <document>,
       {
          writeConcern: <document>, 
          ordered: <boolean>
       }
    )

    参数说明:

    • document:要写入的文档。
    • writeConcern:写入策略,默认为 1,即要求确认写操作,0 是不要求。
    • ordered:指定是否按顺序写入,默认 true,按顺序写入。

image.png

select 查询操作

  1. 查询文档
    db.<collection>.find()

    db.collection.find(
        query, 
        projection
    )

    参数说明:

    • query :可选,使用查询操作符指定查询条件
    • projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)
  2. 查询一个文档
    db.<collection>.findOne()

update 更新

  1. 更新集合
    db.<collection>.update()

    db.collection.update( 
        <query>, 
        <update>, 
        { 
            upsert: <boolean>, 
            multi: <boolean>, 
            writeConcern: <document> 
        } 
    )

    参数说明:

    • query : update 的查询条件,类似与 sql 语句中的 update 查询内的 where 后面的条件。
    • update : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的
    • upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
    • multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
    • writeConcern :可选,抛出异常的级别。
  1. 插入一个文档,如果主键重复则更新。(类似于 mysql 中的 insertAndUpdate)(3.2+ 废弃)
    db.<collection>.save(document)

    db.collection.save( 
        <document>, 
        { 
            writeConcern: <document> 
        } 
    )

    参数说明:

    • document : 文档数据。
    • writeConcern :可选,抛出异常的级别。

更多实例

// 只更新第一条记录:
db.col.update( { "count" : { $gt : 1 } } , { $set : { "test2" : "OK"} } );

// 全部更新:
db.col.update( { "count" : { $gt : 3 } } , { $set : { "test2" : "OK"} },false,true );

// 只添加第一条:
db.col.update( { "count" : { $gt : 4 } } , { $set : { "test5" : "OK"} },true,false );

// 全部添加进去:
db.col.update( { "count" : { $gt : 5 } } , { $set : { "test5" : "OK"} },true,true );

// 全部更新:
db.col.update( { "count" : { $gt : 15 } } , { $inc : { "count" : 1} },false,true );

// 只更新第一条记录:
db.col.update( { "count" : { $gt : 10 } } , { $inc : { "count" : 1} },false,false );

delete 删除操作(没啥用,还是不会的好)

  1. 删除集合(删除所有记录)
    db.<collection>.drop()
  2. 删除文档
    db.<collection>.remove()

    db.collection.remove( 
         <query>, 
         { 
             justOne: <boolean>, 
             writeConcern: <document> 
         } 
     )

    参数说明:

    • query :(可选)删除的文档的条件。
    • justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。
    • writeConcern :(可选)抛出异常的级别。
  3. 删除文档(一个)
    db.<collection>.deleteOne(<query>)
  4. 删除文档(多个)
    db.<collection>.deleteMany(<query>)

where 条件

  1. db.col.find({"author":"www.lilnong.top"}).pretty() 查询所有 author=="www.lilnong.top" 的记录
  2. db.col.find({"author":/nong/}).pretty() 模糊查询所有 author包含 nong 的记录
  3. db.col.find({"likes":{$lt:50}}).pretty() 查询所有 likes < 50 的记录
  4. db.col.find({"likes":{$lte:50}}).pretty() 查询所有 likes <= 50 的记录
  5. db.col.find({"likes":{$gt:50}}).pretty() 查询所有 likes > 50 的记录
  6. db.col.find({"likes":{$gte:50}}).pretty() 查询所有 likes >= 50 的记录
  7. db.col.find({"likes":{$ne:50}}).pretty() 查询所有 likes != 50 的记录
  8. db.col.find({"likes":{$eq:50}}).pretty() 查询所有 likes == 50 的记录
  9. db.col.find({"author":"www.lilnong.top","likes":{$lt:50}}).pretty() 查询所有 author=="www.lilnong.top" && likes < 50 的记录
  10. db.col.find({$or:[{"author":"www.lilnong.top"},{"likes":{$gt:50}}]}).pretty() 查询所有 author=="www.lilnong.top" or likes > 50 的记录

分页(Limit 与 Skip)

使用 limit()方法来读取指定数量的数据
使用 skip() 方法来跳过指定数量的数据

db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)

排序

使用 sort() 方法来排序,1 为升序排列,而 -1 是用于降序排列。

db.COLLECTION_NAME.find().sort({links: 1})
表示以 links 字段升序排列

使用 NodeJS 操作 MongoDB 数据库

常用的有两个库,mongodbmongoose

mongodb

The official MongoDB driver for Node.js. Provides a high-level API on top of mongodb-core that is meant for end users.

安装与引入 mongodb

npm install mongodb --save
var MongoClient = require('mongodb')

await、async 方式调用

image.png

var MongoClient = require('mongodb').MongoClient;
// console.log(MongoClient)
MongoClient.connect(
    'mongodb://localhost:27017/sf-mongodb',
    {},
    async function(err, db){
        if(err) return console.error(err)
        // console.log(db);
        var dbo = db.db('sf-mongodb');
        // var data = await dbo.collection('user').find().toArray();
        // console.log(data)
        
        // 查询历史数据
        // data = await find2array(dbo, 'user');
        // console.log(data)
        consoleFindResult(dbo)        

        // 清空历史数据
        await dbo.collection('user').deleteMany({})
        consoleFindResult(dbo)
        
        // 批量插入数据 CURD之C create
        await dbo.collection('user').insertMany([
            {author: 'www.lilnong.top', operManyCount: 1, operKey: 'insertMany', time: new Date()},
            {author: 'www.lilnong.top', operManyCount: 2, operKey: 'insertMany', time: new Date()}
        ])
        consoleFindResult(dbo, 'C-Many')

        // 单条插入数据 CURD之C create 
        await dbo.collection('user').insertOne({author: 'www.lilnong.top', operKey: 'insertOne', time: new Date()})
        consoleFindResult(dbo, 'C-One')

        // 批量更新数据 CURD之U update
        await dbo.collection('user').updateMany({operKey: 'insertMany'},{$set: {lastUpdateTime: new Date()}})
        consoleFindResult(dbo, 'U-Many')
        
        // 单条更新数据 CURD之U update
        await dbo.collection('user').updateOne({operKey: 'insertMany'},{$set: {lastUpdateTime: new Date()}})
        consoleFindResult(dbo, 'U-One')

        // 读取数据 CURD之R read
        console.log('R', await dbo.collection('user').find().skip(1).limit(1).toArray())
        
        // 删除数据 CURD之D delete
        await dbo.collection('user').deleteOne({operKey: 'insertMany'})
        consoleFindResult(dbo, 'D-One')
    }
)

async function find2array(dbo, collection){
    return dbo.collection(collection).find().toArray(); 
}

async function consoleFindResult(dbo, key){
    var data = await find2array(dbo, 'user');
        console.log(key, data.map(v=>JSON.stringify(v)))
}

回调方式调用

比较原始的方式

var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/sf-mongodb";
 
MongoClient.connect(
    url, 
    { 
        useNewUrlParser: true 
    }, 
    function(err, db) {
      if (err) throw err;
      var dbo = db.db("sf-mongodb");
      dbo.collection('user').insertOne(
        {author: 'www.lilnong.top', operKey: 'insertOne', time: new Date()}, 
        function(err, res) {
            if (err) throw err;
            console.log("文档插入成功", res);
        }
      );
      dbo.collection('user').insertMany(
        [
            {author: 'www.lilnong.top', operManyCount: 1, operKey: 'insertMany', time: new Date()},
            {author: 'www.lilnong.top', operManyCount: 2, operKey: 'insertMany', time: new Date()}
        ], 
        function(err, res) {
            if (err) throw err;
            console.log("文档插入成功", res);
        }
      );
      dbo.collection("user"). find({}).toArray(function(err, result) { // 返回集合中所有数据
        if (err) throw err;
        console.log(result);
      });
      dbo.collection("user").updateOne({}, {$set: {random: Math.random()}}, function(err, res) {
        if (err) throw err;
        console.log("文档更新成功");
      });
      dbo.collection("user").deleteOne({}, function(err, obj) {
        if (err) throw err;
        console.log("文档删除成功");
      });
    }
);

Mongoose

Mongoose 为模型提供了一种直接的,基于scheme结构去定义你的数据模型。它内置数据验证, 查询构建,业务逻辑钩子等,开箱即用。

我感觉就是和一些 ORM 之类的差不多。创建一个模型(model),Mongoose 会自动找到 复数 形式的 collection

支持 MongoDB 的高级( rich )查询语法。 查询文档可以用 modelfind, findById, findOne, 和 where 这些静态方法。要了解 Query api 的更多细节,可以查阅 querying 章节。

安装与引入 Mongoose

安装:npm install mongoose --save
引入:mongoose = require('mongoose')

// Mongoose 的一切始于 Schema。
// 每个 schema 都会映射到一个 MongoDB collection ,并定义这个 collection 里的文档的构成。

    var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/sf-mongodb');

var Schema = mongoose.Schema;
var userSchema = new Schema({
    author: String,
    date: { type: Date, default: Date.now }
});
var User = mongoose.model('User', userSchema);

const user = new User({ author: 'lilnong.1' });
user.save().then(() => console.log('init1', 'success'));
// 直接使用对象也是可以的
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/sf-mongodb');

const User = mongoose.model('User', { author: String });

const user = new User({ author: 'lilnong.2' });
user.save().then(() => console.log('init2', 'success'));

image.png

image.png

CURD

C 保存

const User = mongoose.model('User', { author: String });
const user = new User({ author: 'lilnong' });
user.save().then(() => console.log('init3','success'));

U 更新

const User = mongoose.model('User', { author: String });

User.updateOne(
    {author: 'lilnong.2'}, 
    {author: 'lilnong.3'}
).then(console.log)

R 读取

const User = mongoose.model('User', { author: String });

// 查询全量数据
User.find().then(console.log)

// 查询 author == 'lilnong.test' 的数据
User.find({ author: 'lilnong.test' }).then(console.log)

D 删除

const User = mongoose.model('User', { author: String });

// 删除所有 author 为空的
User.remove({author: null}).then(console.log);

image.png

微信公众号:前端linong

clipboard.png

参考文献

  1. 前端培训目录、前端培训规划、前端培训计划
  2. mongoosejs
阅读 1.2k

javascript-lNong
只此一生,何必从众

Read-Search-Ask

21.7k 声望
4.8k 粉丝
0 条评论
你知道吗?

Read-Search-Ask

21.7k 声望
4.8k 粉丝
宣传栏