关于mongoose:web前端技术Mongoose详解

简介 之前咱们都是通过 shell 来实现对数据库的各种操作的,在开发中大部分时候咱们都须要通过程序来实现对数据库的操作。 而 Mongoose 就是一个让咱们能够通过 Node 来操作 MongoDB 的模块。 Mongoose 是一个对象文档模型(ODM)库,它对 Node 原生的 MongoDB 模块进行了进一步的优化封装,并提供了更多的性能。 在大多数状况下,它被用来把结构化的模式利用到一个 MongoDB 汇合,并提供了验证和类型转换等益处。 mongoose 的益处 能够为文档创立一个模式构造(Schema) 能够对模型中的对象/文档进行验证 数据能够通过类型转换转换为对象模型 能够应用中间件来利用业务逻辑挂钩 比 Node 原生的 MongoDB 驱动更容易 新的对象 mongoose 中为咱们提供了几个新的对象– Schema(模式对象) Schema 对象定义束缚了数据库中的文档构造– Model Model 对象作为汇合中的所有文档的示意,相当于 MongoDB 数据库中的汇合 collection– Document Document 示意汇合中的具体文档,相当于汇合中的一个具体的文档 通过 mongoose 连贯 MongoDB 应用 Mongoose 必须先装置 mongoose 包– npm install mongoose 加载 Mongoose– const mongoose = require("mongoose") 连贯数据库– mongoose.connect("mongodb://地址")– 地址例子:mongodb://127.0.0.1/mg_test 断开连接– mongoose.disconnect() ...

March 29, 2022 · 2 min · jiezi

关于mongoose:Mongoose在ExpressKoa-Egg中使用对比

Mongoose是什么?简略一句话概括:Mongoose是一套操作MongoDB数据库的接口。 开始在应用mongoose之前,须要当时装置好Node环境和MongoDB数据库。以上准备就绪咱们就能够了。 在Express Koa Egg中的应用在Express中首先初始化我的项目 npm init //初始化我的项目npm i xxx --save//装置各种依赖例如express nodemon ...目录如下 |-express| | -- db//启动mongodb数据库的dbpath门路| | --model//数据库中表的模型| | --node_modules| | --public//公共资源| | --route//路由| | --schema//模式类型| | --app.js//入口文件| | --package.json//配置文件装置mongoose。 npm install mongoose//装置mongoose在package.json {"dependencies": { "body-parser": "^1.19.0", "connect-multiparty": "^2.2.0", "express": "^4.17.1", "formidable": "^1.2.2", "http-proxy-middleware": "^2.0.0", "mongoose": "^5.12.13", "multer": "^1.4.2", "multiparty": "^4.2.2", "nodemon": "^2.0.7", "xlsx": "^0.17.4"}}在app.js中引入依赖 const express=require("express");//引入expressconst mongoose = require('mongoose');//引入mongooseconst app=express();const port=8080;//端口号mongoose.connect('mongodb://localhost:27017/Management',{useNewUrlParser:true,useUnifiedTopology:true},function(err){ if(err){ console.log('链接失败'); }else{ console.log('链接胜利'); }});//链接数据库名Mangagement端口号27017,勾销数据库启动正告,app.listen(port,()=>{ console.log(`Example app listening at http://localhost:${port}`) })开启数据库在装置mongodb/bin目录执行cdm执行如下指令 ...

March 1, 2022 · 4 min · jiezi

关于mongoose:用expressmongoose快速开发API接口

1.初始化我的项目npm init -y 2.应用Express框架创立服务器,用mongoose连贯数据库,cors解决跨域npm i express mongoose cors 3.新建一个文件夹http_serve,目录构造 3.1 index.js文件,启动node服务 const express = require('express')const cors = require('cors')const app = express()//解决跨域app.use(cors())//express内置了post参数解析app.use(express.urlencoded({ extended: false }))const apiRouter = require('./router')app.use(apiRouter)app.listen(3008, function () { console.log('app is runing at port 3008');})3.2 db.js 连贯mongoDB const mongoose = require('mongoose')const IP = 'localhost'const PORT = 27017const DB_NAME = 'org'//连贯mongoose.connect(`mongodb://${IP}:${PORT}/${DB_NAME}`, { useNewUrlParser: true})//连贯胜利mongoose.connection.on('connected', () => { console.log('Mongoose connection success')})//连贯异样mongoose.connection.on('error', (err) => { console.log('Mongoose connection error:' + err)})//连贯胜利mongoose.connection.on('disconnected', () => { console.log('Mongoose connection disconnected')})module.exports = mongoose3.3 router.js 定义接口以及办法 ...

January 26, 2022 · 2 min · jiezi

关于mongoose:mongoose中new-schema啥意思

Mongoose 是一个让咱们能够通过Node来操作MongoDB数据库的一个模块Mongoose 是一个对象文档模型(ODM)库,它是对Node原生的MongoDB模块进行了进一步的优化封装大多数状况下,他被用来把结构化的模式利用到一个MongoDB汇合,并提供了验证和类型装换等益处基于MongoDB驱动,通过关系型数据库的思维来实现非关系型数据库在 Mongoose 中,所有数据都由一个 Schema 开始创立。每一个 schema 都映射到一个 Mongodb 的汇合(collection),并定义了该汇合(collection)中的文档(document)的模式。定义一个Scheme(模式构造/束缚)const mongoose = require('mongoose');const Schema = mongoose.Schema; const UserScehma = new Schema({ name: { type: String, required: true }, createTime: { type: Date, default: Date.now }, favoriteIds: [String] sex: String, avatar: String, vip: Boolean,})Schema类型有: StringNumberDateBufferBooleanMixedObjectIdArrayschema传参中每一个键名就会映射为一个schema类 实例办法 映射var userModel = mongoose.model(‘User’,UserScehma)参数:1.要映射的汇合名2.创立的束缚(schema对象)通过映射返回的值对数据库进行增、删、改、查 mongoose批改数据库办法:https://blog.csdn.net/qq_4032...

June 2, 2021 · 1 min · jiezi

mongodb用户创建mongoose数据库连接

一、用户创建1、创建超级管理员 a.首先开启Mongo服务,然后切换admin数据库 use admin;b.创建 db.createUser({user:"root",pwd:"ceshi123",roles:[{role:"root",db:"admin"}]});c.修改mongodb.conf配置文件添加代码: auth=true如果有以下代码,可修改 noauth=true // 修改为auth=true保存mongodb.conf文件 d.创建超级管理员之后,重新启动mongodb服务 use admin;db.shutdownServer(); //关闭服务exit;下一步要进入到mongodb安装目录下的bin如果是windows系统,可以直接去mongodb/bin目录下打开命令shell,具体操作方法:按住shift+鼠标左键可快速打开shell,输入启动命令: ./mongod -f /usr/local/mongodb/conf/mongodb.conf./mongod如果是linux服务器,可以直接到mongodb/bin目录下 cd /usr/local/mongodb/bin // 小编mongodb的安装目录是/usr/local./mongod -f /usr/local/mongodb/conf/mongodb.conf./mongod经过以上操作,现在创建了操作mongodb的超级管理员;下边我们针对我们要使用的数据库进行创建管理员 2、创建指定数据库管理员a.进入到指定数据库,这里采用testDB mongo //启动mongodbuse admin;db.auth("root","ceshi123");如果shell出现1则为进入mongodb成功,为0进入失败。进入成功后,执行以下: use testDB;db.createUser({user:"admin",pwd:"test123",roles:[{role:"root",db:"admin"}]}); // 这里role的权限一定是root,否则node-express-mongoose会读不到数据创建后可以查看: show users;如果输出以上输入信息,则添加成功。下面我们来看下 mongodb 一共有哪些权限: 1. 数据库用户角色:read、readWrite; 2. 数据库管理角色:dbAdmin、dbOwner、userAdmin; 3. 集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;4. 备份恢复角色:backup、restore;5. 所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase6. 超级用户角色:root // 这里还有几个角色间接或直接提供了系统超级用户的访问(dbOwner 、userAdmin、userAdminAnyDatabase)7. 内部角色:__systemread:允许用户读取指定数据库readWrite:允许用户读写指定数据库dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profileuserAdmin:允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。root:只在admin数据库中可用。超级账号,超级权限 二、mongoose连接const config = { DB_URL: 'mongodb://admin:test123@127.0.0.1:27017/testDB'};mongoose.connect(config.DB_URL);解释说明:'mongodb://admin:test123@127.0.0.1:27017/testDB'// admin 管理员用户名// test123 管理员密码// testDB 要连接的数据库 参考链接:1、https://blog.csdn.net/zgrbsbf...2、https://blog.csdn.net/szu_lzz...3、https://blog.csdn.net/leihui_...4、https://www.cnblogs.com/leino...5、http://yijiebuyi.com/blog/f9e...

August 17, 2019 · 1 min · jiezi

MongoDB副本集搭建

MongoDBMongoDB是现在最为流行的NoSQL数据库之一。在大数据时代,传统的关系型数据库遇到了高并发读写、海量数据高效存储、高可扩展性和高可用性这些难题。以MySQL为例,在数据量很大需要分表分库的时候,它本身不提供分片能力,需要自己另建服务。 而NoSQL就是为了解决这些问题而诞生了的。注: NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL"。NoSQL有如下优势: 大数据量,可以通过廉价服务器存储大量的数据,轻松摆脱传统mysql单表存储量级限制。高性能,NoSQL通过简单的key-value方式获取数据,非常快速。还有NoSQL的Cache是记录级的,是一种细粒度的Cache,所以NoSQL在这个层面上来说就要性能高很多。灵活的数据模型,NoSQL无需事先为要存储的数据建立字段,随时可以存储自定义的数据格式。而在关系数据库里,增删字段是一件非常麻烦的事情。如果是非常大数据量的表,增加字段简直就是一个噩梦。高可用,NoSQL在不太影响性能的情况,就可以方便的实现高可用的架构。比如mongodb通过mongos、mongo分片就可以快速配置出高可用配置。单机版MongoDB这种配置只适合简易开发时使用,生产使用不行,因为不是高可用的。这里我使用docker快速启动MongoDB服务,MongoDB版本为3.6。 docker-compose.ymlversion: '3'services: mongo1: image: mongo:3.6 environment: - MONGO_INITDB_ROOT_USERNAME=test - MONGO_INITDB_ROOT_PASSWORD=IIm7A5C5GqRWqnLg network_mode: "host" volumes: - ./mongo_data:/data/db - ./mongod.conf:/etc/mongo/mongod.conf - ./log:/var/log/mongodb command: ["--config", "/etc/mongo/mongod.conf"]mongod.confsystemLog: destination: file path: /var/log/mongodb/mongo.log logAppend: falsestorage: dbPath: /data/db indexBuildRetry: true journal: enabled: truenet: port: 40031 bindIp: 0.0.0.0 maxIncomingConnections: 65536docker-compose.yml中network_mode: "host"是让容器直接使用宿主机网络,配置文件中net下port是指定MongoDB服务监听的端口,storage下dbPath指定数据存储目录,开启journal是因为journal文件用于数据库异常退出时恢复数据(默认开启)。windows上会遇到MongoDB无法启动的问题(WiredTiger提示Operation not permitted),解决方法是自己创建顶级的数据卷 version: '3'services: mongo1: image: mongo:3.6 environment: - MONGO_INITDB_ROOT_USERNAME=test - MONGO_INITDB_ROOT_PASSWORD=IIm7A5C5GqRWqnLg network_mode: "host" volumes: - mongo_data:/data/db - ./mongod.conf:/etc/mongo/mongod.conf - ./log:/var/log/mongodb command: ["--config", "/etc/mongo/mongod.conf"]volumes: mongo_data:副本集高可用的一个做法就是做主从,MongoDB给的方案就是副本集(对于分布式存储有分片集合,之后会写)。MongoDB副本集中主服务器负责整个副本集的读写,副本集定期同步数据备份,一但主节点挂掉,副本节点就会选举一个新的主服务器,这一切对于应用服务器不需要关心。这样的机制提高了数据的可用性,并可以保证数据的安全性。 ...

July 13, 2019 · 1 min · jiezi

基于ReactDvaJSUmiJSAntdesignexpressmongo搭建的CMS内容管理后台

项目地址前端部分:React+Ant-design+DvaJS+UmiJS - 地址(欢迎star&fork&issue)后端部分:express+mongoose+redsi(鉴权)+pm2 - 地址(欢迎star&fork&issue)项目简介此项目为初中级项目,主要为理解React+Ant-design+DvaJS+UmiJS搭建中后台系统结构后端项目为通用模型,包含用户管理,角色管理,内容管理,评论管理,内容分类管理,适用于任何内容型产品后台(博客、社区等,可以直接套个简易版CNode)项目预览在线演示地址

June 18, 2019 · 1 min · jiezi

VuejsEggjsMongodb前后端分离的个人网站

AntVueBlogFrontVue.js+Egg.js+Mongodb前后端分离的个人网站博客。博客地址:ANT (ssr渲染参考AntVueBlogFrontSSR) 主要技术栈前端:vue.js、vue-router、vuex AntVueBlogFront后端:Egg.js、Mongodb AntEggBlogService后台管理: vue.js、vue-router、vuex AntVueBlogAdmin博客功能前台页面文档列表分类标签归档评论(暂时关闭)文章检索后台管理发布文章、存为草稿文章管理标签管理分类管理登录验证Setup运行环境 node.jsmongoDB克隆远程库 git clone git@github.com:antbaobao/AntVueBlogFront.git安装依赖 cd AntVueBlogFrontnpm i运行 npm run dev目录│ .babelrc babel配置│ .editorconfig 编辑器配置│ .eslintignore eslint忽略│ .eslintrc.js eslintrc配置│ .gitignore git上传忽略│ .postcssrc.js│ Dockerfile docker 配置│ index.html 打包模板│ package.json│ README.md│├─build├─src│ │ main.js 项目入口│ │ App.vue 根组件│ │ index.css 全局样式│ ││ ├─api api 请求接口│ ││ ├─assets 外部引用文件│ │ ├─css│ │ └─js│ ││ ├─components vue组件│ ││ ├─ layout 页面公共结构│ ││ ├─store vuex文件│ ││ ├─utils 工具函数│ ││ └─views 页面vue文件│├─test└─static 静态文件部署部署流程可以参考使用docker部署网站 ...

May 31, 2019 · 1 min · jiezi

mongoose无字段模糊查询

参数const val = req.body.val;const reg = new RegExp(val, 'i');Model.find({ $or: [ { key1: {$regex: reg} }, { key2: {$regex: reg} }, { key3: {$regex: reg} } ]}).sort({timestamp: -1}).exec((err, docs) => { // do something})

May 29, 2019 · 1 min · jiezi

mongodb的model名称细节

最近研究api设计,顺便研究了下mongodb,教程没有仔细看过,所以使用过程中也遇到了一些诡异的现象。 比如我使用中发现,我创建的模型名称,在对应数据库的collections内的名称不一致。我很纳闷,比如我创建的如下: const PersonModel = Mongoose.model("person", { firstname: String, lastname: String});当我将一条数据写入后,用工具Robo 3T发现,名称居然变成了people。 后来查了相关资料,原来mongodb有自己的一套规则,详细的规则,比如我这条:mongoose/lib/utils.js。当然这个是历史版本的例子了。关于这个现象,最新文档中也指出: The first argument is the singular name of the collection your model is for. Mongoose automatically looks for the plural version of your model name. For example, if you use const MyModel = mongoose.model('Ticket', mySchema);Then Mongoose will create the model for your tickets collection, not your ticket collection. 一般情况他会创建一个复数的model,这种person算特殊的了。所以你写得model不一定在查询的时候会一样,即便不一样也不要惊讶哦~

May 22, 2019 · 1 min · jiezi

webflux-用户管理界面

一个简单的用户管理的CRUD已经完成,现在我们需要在页面上展示,方便用户管理。尽管现在已经流行前后分离开发,但是在一些小公司做的项目并不需要前端开发人员,页面也是后端开发在写。所以这次我们使用thymeleaf来开发页面。1 集成thymeleafpom文件依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>开启thymeleaf spring.thymeleaf.enabled=true2 创建资源目录在resources目录下创建templates和static目录,templates下放你的html页面,static下放你的css以及js。这些目录是thymeleaf默认的,如果需要修改成别的目录,可以自行配置。感觉没必要修改了。 去bootstrap网站下载生产环境的文件放在static目录下,这样我们写页面就不用关心样式。 3 创建首页controller @Controllerpublic class Index { @GetMapping("/") public String index(){ return "index"; }}页面 首页: <!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8" /><title>欢迎页面</title><link rel="stylesheet" href="/css/bootstrap.css" /></head><body> <div class="container"> <nav class="navbar navbar-default"> <div class="container-fluid"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <a class="navbar-brand" href="#">Mike Study</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li class="active"><a href="#">首页</a></li> <li><a href="#">实战课程</a></li> </ul> <form class="navbar-form navbar-left"> <div class="form-group"> <input type="text" class="form-control" placeholder="你想学点啥?"> </div> <button type="submit" class="btn btn-default">Go</button> </form> <ul class="nav navbar-nav navbar-right"> <li><a href="#">上班摸鱼</a></li> <li><a href="#">下班充电</a></li> </ul> </div> <!-- /.navbar-collapse --> </div> <!-- /.container-fluid --> </nav> <div class="row"> <div class="jumbotron"> <h1>案例上手 Spring Boot WebFlux!</h1> <p>本课程是一个系列基础教程,目标是带领读者上手实战,课程以新版本 Spring Boot 2.0 WebFlux 的核心概念作为主线。围绕 Spring Boot 2.0 WebFlux 技术栈的系列教程,目标是带领读者了解 Spring Boot 2.0 WebFlux 各种特性,并学会使用 Spring Boot 相关技术栈上手开发项目。</p> <blockquote> <p>只有不断地学习才能进步</p> <footer> Mike <cite title="Source Title">Liu</cite> </footer> </blockquote> </div> </div> <div class="row"> <div class="col-md-3"> <img src="https://img.mukewang.com/55f8d5080001293c06000338-240-135.jpg" alt="..." style="height: 140px; width: 100%; display: block;" class="img-thumbnail"> <a href="/users"><p>mongodb开发用户管理系统<span class="label label-danger">mongodb</span></p></a> <p>发布时间:<i class="glyphicon glyphicon-calendar"></i>2019-01-01</p> </div> <div class="col-md-3"> <img src="https://img.mukewang.com/55f8d5080001293c06000338-240-135.jpg" alt="..." style="height: 140px; width: 100%; display: block;" class="img-thumbnail"> <p>mongodb开发用户管理系统<span class="label label-danger">mongodb</span></p> <p>发布时间:<i class="glyphicon glyphicon-calendar"></i>2019-01-01</p> </div> <div class="col-md-3"> <img src="https://img.mukewang.com/55f8d5080001293c06000338-240-135.jpg" alt="..." style="height: 140px; width: 100%; display: block;" class="img-thumbnail"> <p>mongodb开发用户管理系统<span class="label label-danger">mongodb</span></p> <p>发布时间:<i class="glyphicon glyphicon-calendar"></i>2019-01-01</p> </div> <div class="col-md-3"> <img src="https://img.mukewang.com/55f8d5080001293c06000338-240-135.jpg" alt="..." style="height: 140px; width: 100%; display: block;" class="img-thumbnail"> <p>mongodb开发用户管理系统<span class="label label-danger">mongodb</span></p> <p>发布时间:<i class="glyphicon glyphicon-calendar"></i>2019-01-01</p> </div> </div> <div class="row"> <div class="col-md-3"> <img src="https://img.mukewang.com/55f8d5080001293c06000338-240-135.jpg" alt="..." style="height: 140px; width: 100%; display: block;" class="img-thumbnail"> <p>mongodb开发用户管理系统<span class="label label-danger">mongodb</span></p> <p>发布时间:<i class="glyphicon glyphicon-calendar"></i>2019-01-01</p> </div> <div class="col-md-3"> <img src="https://img.mukewang.com/55f8d5080001293c06000338-240-135.jpg" alt="..." style="height: 140px; width: 100%; display: block;" class="img-thumbnail"> <p>mongodb开发用户管理系统<span class="label label-danger">mongodb</span></p> <p>发布时间:<i class="glyphicon glyphicon-calendar"></i>2019-01-01</p> </div> <div class="col-md-3"> <img src="https://img.mukewang.com/55f8d5080001293c06000338-240-135.jpg" alt="..." style="height: 140px; width: 100%; display: block;" class="img-thumbnail"> <p>mongodb开发用户管理系统<span class="label label-danger">mongodb</span></p> <p>发布时间:<i class="glyphicon glyphicon-calendar"></i>2019-01-01</p> </div> <div class="col-md-3"> <img src="https://img.mukewang.com/55f8d5080001293c06000338-240-135.jpg" alt="..." style="height: 140px; width: 100%; display: block;" class="img-thumbnail"> <p>mongodb开发用户管理系统<span class="label label-danger">mongodb</span></p> <p>发布时间:<i class="glyphicon glyphicon-calendar"></i>2019-01-01</p> </div> </div> </div></body></html> ...

May 9, 2019 · 4 min · jiezi

mongodb数据库及数据分页

在做自己的一个小项目时,新学习了mongodb非关系型数据库,使用了mongoose封装好的查询方法,包括数据库分页用到的limit和skip方法,这里记录下。1. mongodb数据库连接参照官网文档对应的参数如下:mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]使用mongoose进行数据库的连接const dataBaseUrl = config.admin.username ? `mongodb://${config.admin.username}:${config.admin.pwd}@${config.host}/share-resource` : `mongodb://${config.host}/share-resource`;mongoose.connect(dataBaseUrl, { useNewUrlParser: true });若出现警告信息:要求使用新的编译方式,则在连接的时候加上useNewUrlParser: trueDeprecationWarning: current URL string parser is deprecated, and will be removed in a future version. To use the new parser, pass option { useNewUrlParser: true } to MongoClient.connect.mongoose.connect(dataBaseUrl, { useNewUrlParser: true });在连接数据库时,对连接操作进行监听处理mongoose.connection.on('connected', function() { console.log('Mongoose connection open to ' + dataBaseUrl);});/* 连接数据库异常 */mongoose.connection.on('error', function(err) { console.log('Mongoose connection error:' + err);});/* 连接数据库断开 */mongoose.connection.on('disconnected', function() { console.log('Mongoose connection disconnected');});2. 数据类型(mongoose中提供的schemaTypes)数据类型有:String,Number,Date,Buffer,Boolean,ObjectId,Array,Mixed,Map,Decimal128在数据库直接用insert方法进行数据插入时,若不强制指定数字的类型,则默认是插入double型数字3. mongoose对数据库操作的方法3.1 数据的插入先要新建schema文件const mongoose = require('../database/mongodbHelper');const Message= mongoose.Schema;const RecordModel = new Message({ message: String, name: String, num: Number,},{ versionKey: false});module.exports = mongoose.model('using_records', RecordModel);在使用schema对进行数据的插入时,若直接插入,则会在新的集合中多出一个_v字段,这个代表的是集合的版本号,可以在schema中加入versionKey: false来删除_v字段数据插入:使用save方法const record= new Record({ message: req.body.message, name: req.body.name, num: req.body.num,});record.save((err, docs) => { if (err) { res.send({ 'status': -1, 'msg': '插入失败' }); } else { res.send({ 'status': 200, 'msg': '插入成功', 'result': ''}); }});3.2 数据的查询使用find方法record.find((err, docs) => { if (err) { res.send({ 'status': -1, 'msg': '参数错误' }); } else { res.send({ 'status': 200, 'msg': '查询成功', 'result': docs}); }});3.3 数据的更新更新一条数据:updateOne/* 第一个参数为查询参数,第二个为要更新的内容,第三个为回调方法 */record.updateOne({_id: id}, updateInfo, (err, doc) => { if(err) { res.send({'status': -1, 'msg': '更新失败', 'result': ''}); } else { res.send({'status': 200, 'msg': '更新成功', 'result': ''}); }})更新多条数据:updateManyrecord.updateMany({user_info: {$elemMatch: {user_id: userId, status: 1, is_delete: 1}}}, {$set: {'user_info.$.is_delete': 3}}, (err, doc) => { if(err) { res.send({'status': -1, 'msg': '参数错误'}); } else { res.send({'status': 200, 'msg': '清空成功'}); }})3.4 数据的删除/* 第一个为要删除的内容的参数 */record.findOneAndDelete({_id: req.body.id}, (err, doc) => { if(err) { res.send({'status': -1, 'msg': '删除失败'}); } else { res.send({'status': 200, 'msg': '删除成功'}); }})4. 数据库的分页操作(limit和skip方法)limit()方法为限制数据库每次查询的数据条数;skip(param)跳过param条数据不查询/* page: 页码;pagesize: 每页的数量 */let page = req.body.page;let pagesize = req.body.pagesize;let queryResult = collection.find(queryCondition).limit(pageSize).skip((page - 1) * pageSize).sort({'_id': -1});queryResult.exec((err, value) => { if(err) { reject(err); } else { resolve({total, value}); }})5.匹配数据匹配数据中的数组里的某个对象里的某个字段,使用$set来设置对应的值$set: {'user_info.$.status': 1}$elemMath只匹配第一条数据,当数组里存在多条一样的数据时,只返回第一条数据let arr = [ { is_delete: 1, name: 'a' }, { is_delete: 1, name: 'b' }]{$elemMatch: {is_delete: 1}}只匹配arr的第一条数据aggregate匹配多条数据/* aggregate聚合操作,$unwind将数组拆分成单个元素 * $group 分组依据 * $sum 统计 * $project 将返回值进行筛选,是否返回筛选完后的某个字段 * */ message.aggregate([ { $match: { 'user_info.user_id': id, 'user_info.is_delete': 0 } }, { $unwind: '$user_info' }, { $group: { _id: {status: '$user_info.status',}, count: {$sum: 1} } }, { $project: { '_id': 0, 'status': '$_id.status', 'count': 1 } } ]).then()对于匹配数组里的某项中的某个字段let arr = [ { is_delete: 1, name: 'a' }, { is_delete: 1, name: 'b' }]/* 匹配arr中的name */$match: { 'arr.name': 'a'}/* 分组筛选 */$ group: { _id: {name: '$arr.name'}}对对象中的数组进行插入数据操作let obj = { id: 1, arr: [ { is_delete: 1, name: 'a' }, { is_delete: 1, name: 'b' } ]}{'$push': {arr: {name: 'c', is_delete: 0}}}正在努力学习中,若对你的学习有帮助,留下你的印记呗(点个赞咯^_^)往期好文推荐: ...

April 23, 2019 · 2 min · jiezi

一个基于material-ui+react+koa2+mongoose的个人博客系统

前言做这玩意主要是有两个目的,练习平时工作中用不到的技术点,在熟练的基础之上去研究其原理。可能的话,替换掉自己的博客系统。项目地址: https://github.com/2fps/blooog前端前端是基于react的,用到了react-router和redux。UI库主要是material-ui,当然css-in-js的方式还只是会使用,抽空去了解下原理。项目截图就不放了,demo地址:http://132.232.131.250:3000 。用户名和密码都是admin。实现的功能文章的显示、编辑和删除功能。标签的显示、编辑和删除功能。站点信息的配置和显示。登录和修改密码功能。后端后端基于koa2和mongoose。实现的功能加密登录。log4js日志记录功能。joi对数据进行验证。已知问题审美不太好,只觉得别人的界面好,自己搞起来就那样。。后端安全没有做好,没有防xss等。前端代码较乱,还未整理,公共方法未剥离。数据库没有使用事务。没有对数据做缓存。等等。后续待加入菜单。评论。等等。。

March 10, 2019 · 1 min · jiezi

nuxt+koa+ant-design-vue+mongoose开发的微信公众号文章管理

github欢迎star https://github.com/aoping/nux…关键词服务端渲染 微信公众号开发 nuxt koa ant-design mongoose功能介绍后台登录 注册 公众号增删改查 文章增删改查公众号自动回复 网页授权 自定义分享 设置菜单等界面展示首页登录注册页公众号管理页文章管理页移动端

February 22, 2019 · 1 min · jiezi

mongoose总结

常用的mongoose操作(增删改查)增–create let message = {}; Model.create(message, (err, result) => {callback}); 或者 let docs = await Model.create(message); // 结合async await使用添加多条数据–insertMany let message = []; Model.insertMany(message, (err, docs) =>{callback}); 或者 let docs = await Model.insertMany(message); // 结合async await使用删-remove 通过条件删除 let message = {name: “张三”};//删除条件 Model.remove(message, (err, result) => {callback}); 或者 let docs = await Model.remove(message); // 结合async await使用 通过id删除 let id = _id // 数据中的_id Model.findByIdAndRemove(id, (err, result) => {callback}); 或者 let docs = await Model.findByIdAndRemove(id); // 结合async await使用改-update 通过条件修改 let conditions = {name: “张三”, age: 22};//修改条件 let message = {name: “张三啊啊”, age: 33}; // 修改内容 Model.findOneAndUpdate(conditions, message, {new, true}, (err, result) => {callback}) 或者 let docs = await Model.updateOneAndUpdate(conditions, message); // 结合async await使用 通过id修改 let id = _id // 数据中的_id let message = {name: “张三啊啊”, age: 33}; // 修改内容 Model.updateByIdAndUpdate(id, message, {new, true}, (err, result) => {callback}) 或者 let docs = await Model.updateByIdAndUpdate(id, message); // 结合async await使用查–find 通过条件查询 let conditions = {name: “张三”, age: 22};//查询条件 查询多条 // 查询不到返回为一个空数组,不会报错 Model.find(conditions, (err, result) => {callback}) 或者 let docs = await Model.find(conditions); // 结合async await使用 查询一条 Model.findOne(conditions, (err, result) => {callback}) 或者 let docs = await Model.findOne(conditions); // 结合async await使用 通过id查询 let id = _id // 数据中的_id Model.findById(id, (err, result) => {callback}) 或者 let docs = await Model.findById(id); // 结合async await使用Tips:update更新数据,默认返回为更新前的数据,需要第三个参数增加{new: true}find查询数据,没有数据返回的是一个空数组,需判断数组的lengthfind查询返回数组,findOne和findById返回的是对象复杂条件查询· 正则表达式 – $regexlet reg = new RegExp();Model.find({$regex: reg}, “$options”:“i”); // “$options”:“i” 控制大小写· 比较运算符 $equals 等于 / $gt 大于 / $gte 大于等于 / $lt 小于 / $lte 小于等于 / $ne 不等于 · 元素是否存在 – $exists Model.find({id: {$exists: true});· 逻辑运算符 $or 或 / $and 与 / $nor 非· 其他查询条件.limit()查询条数 .sort()查询排序 // -1为倒叙 .count()数量.skip()跳过前几个查询结果 ...

January 22, 2019 · 2 min · jiezi

node.js之mongoose的使用

概念Mongoose是一个对象文档模型(ODM)库,它对Node原生的MongoDB模块进行了进一步的优化封装,并提供了更多的功能。mongoose的优势在于:可以为文档创建一个模式结构(Schema)。可以对模型中的对象/文档进行验证。数据可以通过类型转换转换为对象模型。可以使用中间件来应用业务逻辑挂钩。比Node原生的MongoDB驱动更容易。Mongoos的几个对象概念:Schema(模式对象):Schema对象定义约束了数据库中的文档结构Model:Model对象作为集合中的所有文档的表示,相当于MongoDB数据库中的集合collectionDocument: Document表示集合中的具体文档mongoose安装npm i mongoose –save关于npm install、npm install –save的区别来自于https://blog.csdn.net/qq_3037…mongoose基本操作引入mongooselet mongoose = require(“mongoose”);连接数据库mongoose.connect(‘mongodb://user:pwd@ip:27017/database’);事件监听let db = mongoose.connection;db.on(’error’,()=>{ console.log(‘连接失败’);});db.once(‘open’,()=>{ console.log(‘连接成功’);});db.once(‘close’,()=>{ console.log(‘断开连接’);});schema和modellet Schema = mongoose.Schema;let personSchema = new Schema({ name:String, age:Number, sex:{ type:String, default:“F” }});关于schema的学习来自于:关于数据库schema:https://www.cnblogs.com/csnip…关于mongoose的schema:https://www.jianshu.com/p/9ff…let personModel = mongoose.model(“persion”,personSchema);crud操作因为我在启动mongodb时加了 –auth参数,插入操作是需要验证用户权限。db.createUser({ user: “test01”, pwd: “test01”, roles: [{ role: “readWrite”, db: “test” }] })//插入操作/personModel.create({ name:“t01”, age:22},(err)=>{ if(!err){ console.log(“插入成功”); }else{ throw err; }});///修改操作//update报错: DeprecationWarning: collection.update is deprecated. Use updateOne, updateMany, or bulkWrite instead.,改成updateOne/personModel.updateOne({_id:“5c2d7c0bda87713ff850c6ea”},{$set:{name:“t02”}},(err)=>{ if(err){ throw err; }});//personModel.updateOne({_id:“5c2d7af402a3462c7c212b58”},{$set:{name:“t01”}},(err)=>{ if(err){ throw err; }});///查找/personModel.find({},(err,docs)=>{ if(!err){ console.log(docs); }else{ throw err; }});//personModel.find({name:“t01”},(err,docs)=>{ if(!err){ console.log(docs); }else{ throw err; }});//personModel.find({},“name age _id”,{skip:1,limit:2},(err,docs)=>{ if(!err){ console.log(docs); }else{ throw err; }});///删除/personModel.remove({name:“t03”},(err)=>{ if(!err){ console.log(“删除成功”); }});/ ...

January 3, 2019 · 1 min · jiezi

mongoose再认识(三)

今天,说一个常见的知识点插件。对于不熟悉mongoose的人可能会问mongoose中也有插件?这个别说还真的有。那么,在mongoose中的插件如何使用?mongoose插件的使用它和通常用的JavaScript的插件一样,都是为了实现代码的重用。同mongoose再认识(二)中介绍的方法类似。可以在Schema的实例上添加。首先,介绍一个api schema.add(),这个方法可以实现对Schema的扩充。那么,可以紧接着mongoose再认识(二)中的代码来说,修改它的代码如下:let UserSchema = new mongoose.Schema({ firstname: String, lastname: String})UserSchema.add({ createAt: { type: Date, default: Date.now }, updateAt: { type: Date, default: Date.now }})UserSchema.pre(‘save’, function(next) { let now = Date.now() this.updateAt = now; if (!this.createAt) this.createAt = now;})将createAt和updateAt的代码提取出来,因为在开发中,很多collection都需要它们,同样也可能需要用到它的处理方法。所以,用一个插件将它们封装起来变得很有必要。可参考如下代码:module.exports = function(schema) { schema.add({ createAt: { type: Date, default: Date.now }, updateAt: { type: Date, default: Date.now } }) schema.pre(‘save’, function(next) { let now = Date.now() this.updateAt = now; if (!this.createAt) this.createAt = now; })}文件名为time-plugin.js然后,在使用它的UserSchema定义中引用它。代码如下:let UserSchema = new mongoose.Schema({ firstname: String, lastname: String})let timePlugin = require(’../plugins/time-plugin.js)userSchema.plugin(timePlugin)在cnode-club的源码中定义了一个base_model.js文件,这个文件分别在topic.js 、 user.js等文件中进行了引用。 ...

December 25, 2018 · 1 min · jiezi

mongoose再认识(二)

在开发中,除了使用mongoose进行一些基本的操作外,就是一些技巧的使用。文章接续mongoose再认识(一),下文中使用代码可参考这篇文章中的。虚拟字段虚拟字段,从字面意思就可以明白,它不是真正的字段,不存在与数据库中,但是当使用model实例查询时,却可以灵活的运用这个字段。注:这个特性是mongoose自己的,与mongo无关。…// 添加了一个虚拟的fullname字段// get fullnameUserSchema .virtual(‘fullname’) .get(() => this.firstname + ’ ’ + this.lastname)// set fullnameUserSchema .virtual(‘fullname’) .set((name) => let arr = name.split(’ ‘), this.firstname = arr[0], this.lastname = arr[1] )// readUserModel .find({}) .exec() .then(doc => { console.log(doc[0]) })查询的结果如下:{ _id: 5c1dc7248aaf9c2c80fee915, firstname: ‘东坡’, lastname: ‘苏’, __v: 0 }那么,如何获取到结果fullname呢?可以通过doc[0].fullname来获取。如何对数据进行保存呢?代码如下:// 模拟AJAX请求保存数据let person2 = new UserModel()person2.fullname = ‘白 李’person2 .save() .then(doc => console.log(doc)) .catch(err => console.log(err))返回结果:{ _id: 5c1dd7ef535df51980e9fd98, firstname: ‘白’, lastname: ‘李’, __v: 0 }这样,在开发的过程中,就不用担心因为字段不匹配而需要修改数据库的问题。这也是它存在的意义。有兴趣的同学可参考node club中对user.js中用户的分级,不需要在建立一个字段用来保存用户的等级,可以用virtual Type通过socre计算来得出来。在Schema定义一些Model实例常用的方法熟悉mongoose的原理的都知道,Model的构造函数是在Schema实例的基础上创造出来的。所以,对于频繁操作的Model实例方法,可以在Schema的实例上进行定义(具体的可参考JavaScript的prototype)。在一个Schema中经常会带有updateAt和createAt这样的字段,通常的情况下,会给它们一个默认的值。userSchema代码修改如下:let UserSchema = new mongoose.Schema({ firstname: String, lastname: String, createAt: { type: Date, default: Date.now }, updateAt: { type: Date, default: Date.now }})在开发中,开发者往往不会手动的处理它们,但是对于跟踪记录一个数据来说又很必要,也不允许用对这些数据任意的修改。那么,应该如何操作它才是最好的呢?当然,最好就是在执行post请求的时候,会有一些方法会根据一定机制自动保存。而mongoose就存在这样的机制,可以在Schema的实例上添加pre的方法,代码如下:UserSchema.pre(‘save’, function(next) { let now = Date.now() this.updateAt = now; if (!this.createAt) this.createAt = now; next()})模拟AJAX请求保存数据:let person3 = new UserModel()person3.fullname = ‘甫 杜’person3 .save() .then(doc => console.log(doc)) .catch(err => console.log(err))返回结果:{ _id: 5c1e006204bad42224374aea, createAt: 2018-12-22T09:14:10.862Z, updateAt: 2018-12-22T09:14:10.877Z, firstname: ‘甫’, lastname: ‘杜’, __v: 0 }这个觉过并不能说明问题,它是Schema定义时和pre方法共同作用的结果。尝试更新数据来验证定义的方法,代码如下:UserModel.findOne({ lastname: ‘杜’}).exec().then(function(doc) { doc.lastname = ‘杜’ doc.firstname = ‘甫’ doc.save() .then(doc => { console.log(doc) }) .catch(err => { console.error(err) })}).catch(err => console.log(err))返回结果:{ _id: 5c1e006204bad42224374aea, createAt: 2018-12-22T09:14:10.862Z, updateAt: 2018-12-22T09:15:04.398Z, firstname: ‘牧’, lastname: ‘杜’, __v: 0 }这里,我们使用save对数据进行更新,当然这对于跟踪用户的操作行为很有好处,但是并不是所有的数据都需要的,而对于哪些不需要的,还是可以考虑使用findOneAndUpdate,updae,updateMany的。细心的同学会发现,其实它和shell命令的db.users.insert({})类似,user.save({})是插入一条数据,而后者则可以插入多条数据。注:在使用操作数据库中的数据时一定要注意,要操作的时user.find()或user.findOne()返回的一整条数据,如果是实例化了一个UserModel,则会造成数据库中的数据丢失。 ...

December 23, 2018 · 1 min · jiezi

mongoose 再认识(一)

mongoose 是一个ODM(Object Data Model)的库,也叫做对象数据模型。那么为什么说是对象数据模型呢?注:MongoDB或者Mongo是NoSQL类型的数据库,也就是说是非关系型的数据库。它被用来处理数据,实现对象间的转换。数据处理:创建一个Schema,提供Schema的数据验证功能。对象的转换:这些对象是指开发过程中创建的对象和MongodDB中代表的相应对象。如果不明白,或者似懂非懂,如果看了下文,相信你会明白不少。常用的术语CollectionsMongo中的Collections相当于关系数据库中的表(tables),它包含了大量的JSON文档(document)。DocumentsDocuments相当于SQL中的记录(records)或者行(rows)。在SQL中需要用多个表,通过数据间的引用来表达数据间的关联,但是在Mongo中可以通过一个Document来实现。SchemaSQL定义一个schema通过表(table)的定义,而MongoDB中是没有这个的,如果我们使用MongoDB直接插入的就是一个document。mongoose它定义了一个schema来表示document 的数据结构或者构造函数,它是建立在应用层面上的,每个docuemnt都是它的示例对象。FieldsFields 或者称之为属性,它相当于SQL中的列(columns),它用来形成一个个schema。Models和Schema一样它也是一个数据结构或者构造函数,不过它更特殊。它使用schema创建了一个Document的实例,这个实例相当于SQL中的记录(record)。mongoose中的 Schema 和 Modelmongoose中的schema是document的构造函数,使用它可以定义一个document的默认值,进行字段(fields)的验证。mongoose中的model提供了一个访问数据的接口,通过它可以实现对document(也可以叫做记录)的CRUD(增,查,改,删)。所以,可以这么说model是Schema的包装器,通过包装实现了Schema结构的数据与MongoDB数据库之间的交互。注:在开发过程中,使用的都是Model和Schema的实例,所以可以理解文章开篇说的对象转换和对象数据模型。具体可参考下面的示例代码。引用mongoose使用前需要先安装mongooe,可通过yarn install mongoose来安装,然后通过如下代码来引用:// 引用mongooselet mongoose = require(‘mongoose’)说明:Schema和Model不是显式的连接到了数据库,为什么这么说呢,因为开发的过程中,不是使用的mongoose.connect(“mongodb://127.0.0.1:27017”)返回的对象创建的Schema和Model,而是直接使用的mongoose的引用,这样做的好处很明显,极大地提升了性能。mongoose定义使用了单例设计模式,所以使用require返回了一个单例对象,这在开发中比较常见,对于写自己的库有指导意义。连接到MongoDB数据库// 引用mongooselet mongoose = require(‘mongoose’)// 连接到demo测试数据库mongoose.connect(‘mongodb://127.0.0.1:27017/demo’)定义一个Schema每一个collection中的所有document都使用同一个Schema定义的field。每一个document对象的键名通过Schema来定义。// 引用mongooselet mongoose = require(‘mongoose’)// 连接到demo测试数据库mongoose.connect(‘mongodb://127.0.0.1:27017/demo’)// 定义并实例化一个Schemalet userSchema = new mongoose.Schema({ firstname: String, lastname: String})同样在Schema中可以对field进行验证,如:firstname是String类型的。Schema的字段值可以是Array,String,Boolean,Buffer,Date,Number,ObjectId,或者Mixed(泛型,或者一个可变化的数据类型)。定义并实例化一个model// 引用mongooselet mongoose = require(‘mongoose’)// 连接到demo测试数据库mongoose.connect(‘mongodb://127.0.0.1:27017/demo’)// 定义并实例化一个Schemalet UserSchema = new mongoose.Schema({ firstname: String, lastname: String})// 定义一个Modellet UserModel = mongoose.model(‘User’, userSchema)// 实例化一个Modellet person = new Usermodel({ firstname: ‘东坡’, lastname: ‘苏’})可能有的人会比较疑惑,为什么Schema的定义和实例化可以放在一起,而Model的定义和实例化要分开?因为schema的实例不牵涉到具体的操作,而Model的实例往往牵涉到复杂的操作。所以前者在开发中往往两个步骤一起来做,后者分开来做。mongoose的CRUD添加数据person .save() .then(doc => { console.log(doc) }) .catch(err => { console.error(err) })查看数据UserModel .find({ lastname: ‘苏’ // query }) .then(doc => { console.log(doc) }) .catch(err => { console.error(err) })更新数据UserModel .findOneAndUpdate( { lasttname: ‘苏’ // query }, { firstname: ‘xxx’ // field:values 的更新 }, { new: true, // 返回更新后的document runValidators: true // 在更新前进行验证 }) .then(doc => { console.log(doc) }) .catch(err => { console.error(err) })删除数据UserModel .findOneAndRemove({ firstname: ‘东坡’ }) .then(response => { console.log(response) }) .catch(err => { console.error(err) })当然,mongoose还提供了很多很实用的api,这里就不多说了。mongoose queries ...

December 22, 2018 · 1 min · jiezi