MongoDB
数据库下载安装与启动
下载地址: https://www.mongodb.com/try/download/community
配置步骤如下:
- 将压缩包移动到
C:\Program Files
下,然后解压 - 创建
C:\data\db
目录,mongodb 会将数据默认保存在这个文件夹 - 以 mongodb 中 bin 目录作为工作目录,启动命令行
- 运行命令
mongod
,看到最后的waiting for connections
则表明服务已经启动成功 - 然后可以使用
mongo
命令连接本机的mongodb
服务
修改mongodb
数据库位置
-
首先创建数据库目录,例如
d:\data
。然后运行命令:mongod -dbpath d:/data
-
配置文件方式,在任意位置创建一个配置文件,例如
c:\mongodb\conf
的目录下创建一个名为master.cfg
的文件,内容为dbpath=d:\data
,然后运行命令:mongod -config c:\mongodb\conf\master.cfg
命令行交互
数据库命令
-
显示所有的数据库
show dbs
-
切换到指定的数据库,如果数据库不存在会自动创建数据库
use 数据库名
-
显示当前所在的数据库
db
-
删除当前数据库
use 库名 db.dropDatabase()
集合命令
-
创建集合
db.createCollection('集合名称')
-
显示当前数据库中的所有集合
show collections
-
删除某个集合
db.集合名.drop()
-
重命名集合
db.集合名.renameCollection('newName')
文档命令
-
插入文档
db.集合名.insert(文档对象);
-
查询文档
db.集合名.find(查询条件)
_id 是 mongodb 自动生成的唯一编号,用来唯一标识文档
-
更新文档
db.集合名.update(查询条件,新的文档) db.集合名.update({name:'张三'},{$set:{age:19}})
-
删除文档
db.集合名.remove(查询条件)
mongoose
简介
Mongoose
是一个让我们可以通过Node
来操作MongoDB
的模块。Mongoose
是一个对象文档模型(ODM)库,它对Node
原生的MongoDB
模块进行了进一步的优化封装,并提供了更多的功能。在大多数情况下,它被用来把结构化的模式应用到一个MongoDB
集合,并提供了验证和类型转换等好处。- mongoose中的对象:
Schema
模式对象(Schema
对象定义约束了数据库中的文档结构)Model
模型对象(Model
对象作为集合中的所有文档的表示,相当于MongoDB
数据库中的集合collection
)Document
文档对象(Document
表示集合中的具体文档,相当于集合中的一个具体的文档)
mongoose的好处
- 可以为文档创建一个模式结构(Schema)
- 可以对模型中的对象/文档进行验证
- 数据可以通过类型转换转换为对象模型
- 可以使用中间件来应用业务逻辑挂钩
- 比Node原生的MongoDB驱动更容易
安装
npm i -S mongoose
连接数据库
config/db.config.js
// 1.引入mongoose
const mongoose = require("mongoose");
// 2.连接mongodb数据库
// 指定连接数据库后不需要存在,当你插入第一条数据库后会自动创建数据库
/*
mongoose.connect('mongodb://数据库地址:端口号/数据库名',{useMongoClient:true})
如果端口号是默认端口号(27017)则可以省略不写
*/
mongoose.connect('mongodb://127.0.0.1:27017/ds2', {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
})
// 3.监听mongodb数据库的连接状态
// 绑定数据库连接成功事件
mongoose.connection.once("open", function () {
console.log("连接成功");
});
// 绑定数据库连接失败事件
mongoose.connection.once("close", function () {
console.log("数据库连接已经断开");
});
// 4.断开数据库连接(一般不用)
mongooes.disconnect();
注意:
MongoDB
数据库,一般情况下,只需要连接一次,连接一次后,除非项目停止服务器关闭,否则连接一般不会断开
创建模式对象和模型对象
数据库中的 Schema
,为数据库对象的集合。schema
是 mongoose
里会用到的一种数据模式,可以理解为表结构的定义;每个 schema
会映射到 mongodb
中的一个 collection
,它不具备操作数据库的能力。
-
每个
schema
都会映射到一个MongoDB
collection
并定义这个collection
里的文档结构 -
支持的字段类型
类型 作用 String 定义字符串 Number 定义数字 Date 定义日期 Buffer 定义二进制 Boolean 定义布尔值 Mixed 定义混合类型 ObjectId 定义对象ID Array 定义数组
model/UserModel.js
const mongoose = require("mongoose")
const Schema=mongooes.Schema;
//创建模式对象
const UserType=new Schema({
name:{
type: 'string',
//添加约束,保证数据的完整性,让数据按规矩统一
require: true
},
age:Number,
gender:{
type:String,
// 默认值
default:'female'
},
address:String
})
//创建模型对象
//通过Schema来创建Model
//Model代表的是数据库中的集合,通过Model才能对数据库进行操作
//mongoose.model(modelName,schema)
//建立映射关系,students是集合,mongoose会自动将集合变成复数比如student会变成students
//大写也会被自动转换为小写,比如Users会变成users
const UserModel=mongoose.model("UserModel",UserType,"user");
//第一个参数表示创建的集合的名称,第二个参数表示利用的模式对象,第三个参数是强行指定集合名称
module.exports = UserModel
文档新增
save()
操作的是文档
代码示例:
var mongoose = require('mongoose')
const UserModel = require('../model/UserModel');
//链式调用 通过new 一个Model创建一个 document
new UserModel({name:"小明",age:18}).save((err,docs) => {
if(!err){
console.log(docs)
res.send({
code: 200,
data: {
id: docs._id,
},
})
//{ _id: 6017bd1cf4cc8544d8ed2a8a, name: '小明', age: 18, __v: 0 }
}
})
create()
操作的是模型
代码示例:
var mongoose = require('mongoose')
const UserModel = require('../model/UserModel');
UserModel.create({name:"小明",age:18},{name:"小红",age:10},(err,doc1,doc2) => {
if(!err){
console.log(doc1)
//{ _id: 6017be2d77c8dd01242624bb, name: '小明', age: 18, __v: 0 }
console.log(doc2)
//{ _id: 6017be2d77c8dd01242624bc, name: '小红', age: 10, __v: 0 }
}
})
//Model.createOne(doc, [callback]); 创建一个对象
//Model.createMany(doc, [callback]); 创建多个对象
// -doc是需要插入的文档
// -callback(err) 是回调函数,可以用来提示是否创建成功了
insertMany()
操作的是模型
UserModel.insertMany({name:"小明",age:18},{name:"小芳",age:14},(err,docs) => {
if(!err){
console.log(docs)
/*[{ _id: 6017befb5c36d64d08b72576, name: '小明', grades: 68, __v: 0 },
{ _id: 6017befb5c36d64d08b72577, name: '小芳', grades: 94, __v: 0 }]*/
}
})
文档查询
find()
代码示例:
var mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student',(err) => {
if(!err){
var schema = new mongoose.Schema({name:String,grades:Number})
var stuModel = mongoose.model('grades',schema)
//查询所有数据
stuModel.find((err,docs) => {
if(!err){
console.log(docs)
}
})
/* [{ _id: 6017befb5c36d64d08b72576, name: '小明', grades: 68, __v: 0 },
{ _id: 6017befb5c36d64d08b72577, name: '小芳', grades: 94, __v: 0 },
{ _id: 6017c455ba09d355a49ec8eb, name: '小红', grades: 52, __v: 0 },
{ _id: 6017c455ba09d355a49ec8ec, name: '小刚', grades: 46, __v: 0 }]*/
//查询成绩大于60以上的数据
stuModel.find({grades:{$gte:60}},(err,docs) => {
if(!err){
console.log(docs)
}
})
/*[{ _id: 6017befb5c36d64d08b72576, name: '小明', grades: 68, __v: 0 },
{ _id: 6017befb5c36d64d08b72577, name: '小芳', grades: 94, __v: 0 }]*/
//查询成绩大于60以上且名字里存在‘芳’的数据
stuModel.find({name:/芳/,grades:{$gte:60}},(err,docs) => {
if(!err){
console.log(docs)
}
})
/*[
* { _id: 6017befb5c36d64d08b72577, name: '小芳', grades: 94, __v: 0 }
* ]*/
//查询名字里存在‘明’的数据且只输出‘name’字段
//_id默认会返回
stuModel.find({name:/明/},{name:1,_id:0},(err,docs) => {
if(!err){
console.log(docs)
}
})
// [{name: '小明'}]
//跳过前两条数据并限制只输出一条数据
stuModel.find(null,null,{skip:2,limit: 1},(err,docs) => {
if(!err){
console.log(docs)
}
})
/*[{ _id: 6017c455ba09d355a49ec8eb, name: '小红', grades: 52, __v: 0 }*/
}
})
findById()
var mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student',(err) => {
if(!err){
var schema = new mongoose.Schema({name:String,grades:Number})
var stuModel = mongoose.model('grades',schema)
//保存查询数据的_id
var aIDArr = []
//查询所有数据
stuModel.find((err,docs) => {
if(!err){
docs.forEach((item,index,arr)=>{
aIDArr.push(item._id)
})
//显示第 0 个元素的所有字段
stuModel.findById(aIDArr[0],(err,doc)=>{
if(!err){
console.log(doc)
}
})
// { _id: 6017befb5c36d64d08b72576, name: '小明', grades: 68, __v: 0 }
//显示第 0 个元素且只输出name字段
stuModel.findById(aIDArr[0],{name:1,_id:0},(err,doc)=>{
if(!err){
console.log(doc)
}
})
// { name: '小明' }
//显示第 0 个元素且输出最少的字段(_id默认输出)
stuModel.findById(aIDArr[0],{lean:true},(err,doc)=>{
if(!err){
console.log(doc)
}
})
// { _id: 6017befb5c36d64d08b72576 }
}
})
}
})
findOne()
var mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student',(err) => {
if(!err){
var schema = new mongoose.Schema({name:String,grades:Number})
var stuModel = mongoose.model('grades',schema)
//找出age>80的文档中的第一个文档
stuModel.findOne({grades:{$gt:80}},(err,doc) => {
if(!err){
console.log(doc)
}
})
//{ _id: 6017befb5c36d64d08b72577, name: '小芳', grades: 94, __v: 0 }
//找出age>80的文档中的第一个文档,且只输出name字段
stuModel.findOne({grades:{$gt:80}},{name:1,_id:0},(err,doc) => {
if(!err){
console.log(doc)
}
})
//{ name: '小芳' }
//找出age>80的文档中的第一个文档,且输出包含name字段在内的最短字段
stuModel.findOne({grades:{$gt:80}},{lern:true},(err,doc) => {
if(!err){
console.log(doc)
}
})
//{ _id: 6017befb5c36d64d08b72577 }
}
})
复杂查询$where
$where
可以使用任意的 JavaScript 作为查询的一部分,包含JavaScript 表达式的字符串或者函数
var mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student',(err) => {
if(!err){
var schema = new mongoose.Schema({name:String,grades:Number})
//添加一个测试字段
// schema.add({test:Number})
var stuModel = mongoose.model('grades',schema)
//添加两条数据
// stuModel.create({name:"小花",grades:76,test:76},{name:"小兰",grades:60,test:30},(err,docs)=>{
// console.log(docs)
// })
//字符串 es5中this与obj指向一样,es6中只能用obj
stuModel.find({$where:"this.grades == this.test" || "obj.grades == obj.test"},(err,doc) => {
if(!err){
console.log(doc)
}
})
//[{_id: 6017d7cb8a95cb2a00aae3ae,name: '小花',grades: 76,test: 76,__v: 0}]
//函数
stuModel.find({$where:function() {
return this.grades == this.test || obj.grades == obj.test*2
}},(err,doc) => {
if(!err){
console.log(doc)
}
})
/*[{_id: 6017d7cb8a95cb2a00aae3ae,name: '小花',grades: 76,test: 76,__v: 0},
{_id: 6017d7cb8a95cb2a00aae3af,name: '小兰',grades: 60,test: 30,__v: 0}]*/
}
})
常用查询条件
$or 或关系
$nor 或关系取反
$gt 大于
$gte 大于等于
$lt 小于
$lte 小于等于
$ne 不等于
$in 在多个值范围内
$nin 不在多个值范围内
$all 匹配数组中多个值
$regex 正则,用于模糊查询
$size 匹配数组大小
$maxDistance 范围查询,距离(基于LBS)
$mod 取模运算
$near 邻域查询,查询附近的位置(基于LBS)
$exists 字段是否存在
$elemMatch 匹配内数组内的元素
$within 范围查询(基于LBS)
$box 范围查询,矩形范围(基于LBS)
$center 范围醒询,圆形范围(基于LBS)
$centerSphere 范围查询,球形范围(基于LBS)
$slice 查询字段集合中的元素(比如从第几个之后,第N到第M个元素
特定类型查询
方法
方法 | 作用 |
---|---|
sort | 排序 |
skip | 跳过 |
limit | 限制 |
select | 显示字段 |
exect | 执行 |
count | 计数 |
distinct | 去重 |
exec()
和then()
两者返回的都是
promise
对象exec
一般用于独立的动作一次性执行,then
则用于连续性的动作。从其方法名也可以区别它们的用法,exec
就是执行的意思,then
就是然后怎么怎么,exec
和then
的参数是有所不同的,前者是callback(err,doc)
,后者则是resolved(doc),rejected(err)
代码示例:
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student')
var Schema =new mongoose.Schema({ name:String,grades:Number,test:{type:Number,default:0}})
var stuModel = mongoose.model('grades', Schema);
// 按test从小到大排序
// 1是升序,-1是降序
stuModel.find().sort({test:1}).exec((err,docs)=>{
console.log(docs)
})
// 按test从大到小排列
stuModel.find().sort('-test').exec((err,docs)=>{
console.log(docs)
})
// 跳过1个,显示其他
stuModel.find().skip(1).exec((err,docs)=>{
console.log(docs)
})
// 显示2个
stuModel.find().limit(2).exec((err,docs)=>{
console.log(docs)
})
// 显示name、grades字段,不显示id字段
stuModel.find().select('name grades -id').exec((err,docs)=>{
console.log(docs)
})
// 跳过第1个后,只显示2个数据,按照grades由大到小排序,且不显示id字段
stuModel.find().skip(1).limit(2).sort('-grades').select('-id').exec((err,docs)=>{
console.log(docs)
//[{ name: '小明', grades: 78, v: 0, test: 1 },{ name: '小花', grades: 76, test: 4, v: 0 }]
})
// 显示集合stuModel中的文档数量
stuModel.find().count((err,count)=>{
console.log(count)
//6
})
// 返回集合stuModel中的grades的值
stuModel.find().distinct('grades',(err,distinct)=>{
console.log(distinct)
//[ 46, 52, 60, 76, 78, 94 ]
})
文档更新
update()
-
Model.update(conditions, doc, [options], [callback])
-
参数
conditions
:查询条件doc
:需要修改的数据(插入的数据)[options]
:控制选项safe (boolean)
: 默认为true
,安全模式。upsert (boolean)
: 默认为false
。如果不存在则创建新记录。multi (boolean)
: 默认为false
。是否更新多个查询记录。runValidators
: 如果值为true
,执行Validation验证。setDefaultsOnInsert
: 如果upsert
选项为true
,在新建时插入文档定义的默认值。strict (boolean)
: 以strict
模式进行更新。overwrite (boolean)
: 默认为false
。禁用update-only
模式,允许覆盖记录。 -
[callback]:回调函数
-
若设置了查询条件,当数据库不满足时默认什么也不发生
-
update()
方法中的回调函数不能省略,否则数据不会更新,当回调无有用信息时可以使用exec()
简化stuModel.update({name:'小明'},{$set:{test:34}}.exec())
代码示例:
//第一步,引入mongoose
const mongoose = require('mongoose')
//第二步,连接数据库
mongoose.connect('mongodb://localhost:27017/student',err=>{
if(!err){
//第三步,创建模板
var Schema =new mongoose.Schema({ name:String,grades:Number,test:{type:Number,default:0}})
// var Schema = new Schema()
//第四步,将模板映射到集合并创建
var stuModel = mongoose.model('grades',Schema)
//查询name为小明的数据,并将其test更改为34
//若有多个文档,默认只更新第一个
stuModel.update({name:'小明'},{$set:{test:34}},(err,raw)=>{
console.log(raw)
})
//{ n: 1, nModified: 1, ok: 1 }
//6017befb5c36d64d08b72576 小明 68 0 34
}
})
updateOne()
Model.updateOne(conditions, doc, [options], [callback])
- 与
update()
相似,唯一区别为updateOne()
默认更新一个文档,即使设置{multi:true}
也只更新一个文档
updateMany()
Model.updateMany(conditions, doc, [options], [callback])
- 与
update()
相似,唯一区别为updateMany()
默认更新多个文档,即使设置{multi:false}
也无法只更新一个文档
find()
+save()
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student',err=>{
if(!err){
var Schema =new mongoose.Schema({ name:String,grades:Number,test:{type:Number,default:0}})
var stuModel = mongoose.model('grades',Schema)
//查询成绩小于60的数据,并在其名字后添加‘:差生’字段
stuModel.find({grades:{$lt:60}},(err,docs)=>{
console.log(docs);
/*[{test: 0,_id: 6017c455ba09d355a49ec8eb,name: '小红',grades: 52,__v: 0},
{test: 0,_id: 6017c455ba09d355a49ec8ec,name: '小刚',grades: 46,__v: 0}]*/
docs.forEach((item,index,arr) => {
item.name += ':差生'
//将修改后的数据保存
item.save()
})
console.log(docs)
/*[{test: 0,_id: 6017c455ba09d355a49ec8eb,name: '小红:差生',grades: 52,__v: 0},
{test: 0,_id: 6017c455ba09d355a49ec8ec,name: '小刚:差生',grades: 46,__v: 0}]*/
})
}
})
findOne()
+save()
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student',err=>{
if(!err){
var Schema =new mongoose.Schema({ name:String,grades:Number,test:{type:Number,default:0}})
var stuModel = mongoose.model('grades',Schema)
//查询成绩小于60的数据,并在其名字后添加‘:差生’字段
stuModel.findOne({name:'小明'},(err,doc)=>{
console.log(doc);
//{test: 34,_id: 6017c455ba09d355a49ec8eb,name: '小明',grades: 68,__v: 0},
doc.age += 10
doc.save()
console.log(docs)
//{test: 34,_id: 6017c455ba09d355a49ec8eb,name: '小明',grades: 78,__v: 0}
})
}
})
findOneAndUpdate()
Model.findOneAndUpdate([conditions], [update], [options], [callback])
findByIdAndUpdate()
Model.findByIdAndUpdate([conditions], [update], [options], [callback])
文档删除
deleteOne()
Model
的deleteOne()
:
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student',err=>{
if(!err){
var Schema =new mongoose.Schema({ name:String,grades:Number,test:{type:Number,default:0}})
var stuModel = mongoose.model('grades',Schema)
//删除名字中包含‘差生’的数据
stuModel.deleteOne({name:/差生/},function(err){})
// 回调函数不能省略,但可以使用exec() 简写
//stuModel.deleteOne({name:/差生/}).exec()
})
}
})
文档的deleteOne()
:
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student',err=>{
if(!err){
var Schema =new mongoose.Schema({ name:String,grades:Number,test:{type:Number,default:0}})
var stuModel = mongoose.model('grades',Schema)
//删除名字中包含‘差生’的数据
stuModel.find({name:/差生/},function(err,docs){
docs.forEach((item,index,arr)=>{
item.deleteOne((err,doc)=>{
//doc为被删除的值
console.log(doc)
})
})
})
})
}
})
findOneAndRemove()
- 删除符合条件的一条数据
Model.findOneAndRemove(conditions, [options], [callback])
- 回调不可省略,但可以使用
exec()
简写
stuModel.findOneAndRemove({name:/差生/}).exec()
findByIdAndRemove()
- 通过id删除数据(id是唯一的)
Model.findByIdAndRemove(conditions, [options], [callback])
- 回调不可省略,但可以使用
exec()
简写
前后钩子
-
前后钩子即
pre()
和post()
方法(中间件) -
中间件在
schema
上指定,类似静态方法或实例方法等 -
可以在执行以下操作时设置前后钩子
init
validate
save
remove
count
find
findOne
findOneAndRemove
findOneAndUpdate
insertMany
update
-
pre()
:在执行某些操作前执行 -
post()
:在执行某些操作前后执行,不可以使用next()
代码示例:
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student')
var Schema =new mongoose.Schema({ name:String,grades:Number,test:{type:Number,default:0}})
Schema.pre('find',function(next){
console.log('我是pre方法1');
next();
});
Schema.pre('find',function(next){
console.log('我是pre方法2');
next();
});
Schema.post('find',function(docs){
console.log('我是post方法1');
});
Schema.post('find',function(docs){
console.log('我是post方法2');
});
var stuModel = mongoose.model('grades', Schema);
stuModel.find(function(err,docs){
console.log(docs[0]);
})
/*
我是pre方法1
我是pre方法2
我是post方法1
我是post方法2
{test: 34, _id: 6017befb5c36d64d08b72576,name: '小明',grades: 78,__v: 0}
*/
文档验证
required
//将name设置为必填字段,如果没有name字段,文档将不被保存,且出现错误提示
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student')
var Schema =new mongoose.Schema({
name:{
type:String,
required:true
},
age:Number
})
var stuModel = mongoose.model('students', Schema);
new stuModel({age:20}).save((err,doc)=>{
if(err){
return console.log(err)
}
console.log(doc)
})
//报错:name: Path `name` is required.
default
//设置age字段的默认值为18,如果不设置age字段,则会取默认值
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student')
var Schema =new mongoose.Schema({
name:String,
age:{
type:Number,
default:18
}
})
var stuModel = mongoose.model('students', Schema);
new stuModel({name:'李雷'}).save((err,doc)=>{
if(err){
return console.log(err)
}
console.log(doc)
})
//{ age: 18, _id: 6018f3bd7e51343e6c4f212b, name: '李雷', __v: 0 }
min
max
只适用于数字
//将age的取值范围设置为[0,10]。如果age取值为20,文档将不被保存,且出现错误提示
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student')
var Schema =new mongoose.Schema({
name:String,
age:{
type:Number,
min:10,
max:18
}
})
var stuModel = mongoose.model('students', Schema);
new stuModel({name:'李雷',age:20}).save((err,doc)=>{
if(err){
return console.log(err)
}
console.log(doc)
})
//age: Path `age` (20) is more than maximum allowed value (18).
match
//将name的match设置为必须存在'01'字符。如果name不存在'01',文档将不被保存,且出现错误提示
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student')
var Schema =new mongoose.Schema({
name:{type:String,match:/01/},
age:Number,
})
var stuModel = mongoose.model('students', Schema);
new stuModel({name:'李雷',age:20}).save((err,doc)=>{
if(err){
return console.log(err)
}
console.log(doc)
})
//name: Path `name` is invalid (李雷).
enum
//将name的枚举取值设置为['zs','ls','ww'],如果name不在枚举范围内取值,文档将不被保存,且出现错误提示
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student')
var Schema =new mongoose.Schema({
name:{type:String,enum:['zs','ls','ww']},
age:Number,
})
var stuModel = mongoose.model('students', Schema);
new stuModel({name:'lss',age:20}).save((err,doc)=>{
if(err){
return console.log(err)
}
console.log(doc)
})
//name: ValidatorError: `lss` is not a valid enum value for path `name`.
validate
//定义名字name的长度必须在4个字符以上
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student')
var Schema =new mongoose.Schema({
name:{type:String,validate:nameLength},
age:Number,
})
var stuModel = mongoose.model('students', Schema);
new stuModel({name:'abcd',age:20}).save((err,doc)=>{
if(err){
return console.log(err)
}
console.log(doc)
})
function nameLength(arg){
if(arg.length>4){
return true
}
return false
}
//name: Validator failed for path `name` with value `abcd`