node中使用mongoose

下载 mongoose

npm install mongoose

引入 mongoose 并连接数据库

const mongoose = require('mongoose')
const DB_URL = 'mongodb://localhost/mongoose-test' 

mongoose.connect(DB_URL,{useNewUrlParser:true,useUnifiedTopology:true }, (err) => {
  if (err) return console.log(err)
  console.log('数据库成功连接')
})

// 这种也可以看数据库是否连接成功
mongoose.connection.on('connected', () => console.log('数据库连接成功'))
mongoose.connection.on('error', () => console.log('数据库连接异常'))
mongoose.connection.on('disconnectied', () => console.log('数据库连接断开'))

定义Schema

数据库中的Schema,为数据库对象的集合。schema 是 mongoose 里会用到的一种数据模式,可以理解为表结构的定义;每个 schema 会映射到 mongodb 中的一个 collection,他不具备操作数据库的能力

// 设计 users 表(集合) 定义一个Schema Schema里面的对象和数据库表里面的字段需要一一对应
const UserSchema = new mongoose.Schema({
  name: String,
  age: Number,
  status: 'number'
})


/*
  定义数据库模型 操作数据库
  model里面的第一个参数 要注意:首字母大写、要和数据库 (集合) 名称对应
  这个模型会和模型名称相同的复数的数据库建立连接:如通过下面方法创建,那么这个模型将会操作 users 这个表(集合)
  复数 >==== 会给名字多加个s  如:User ===> users   Phone ===> phones
*/

const User = mongoose.model('User', UserSchema)		// 默认会操作users表
// const User = mongoose.model('User', UserSchmea, 'user')	// 默认会操作user表

// 查询
User.find({}, (err, doc) => {
  if (err) {
    console.log(err)
  } else {
    console.log(doc)
  }
})

查询数据

const User = mongoose.model('User', UserSchema)

// {查找 status 是1的} ,{只显示name和age, _id不显示},{找两条数据},(回调函数)
User.find({ status: 1 }, {name: 1, age: 1, _id: 0}, {limit: 2}, (err, doc) => {
  if (err) return console.log(err)
  console.log(doc)
})

User.find({}, (err, doc) => {
  if (err) {
    console.log(err)
  } else {
    console.log(doc)
  }
})

添加数据 单条添加

const User = mongoose.model('User', UserSchema)

/*
  先实例化 Model 通过实例化 User Model 创建添加的数据
  在实例 .save()
*/
const newUser = new User({	// 实例化模型 传入增加的数据
  name: '李四',
  age: 18,
  status: 1
})

// 第二个参数返回的是 添加成功的数据
newUser.save((err, v) => {
  if (err) return console.log(err)
  console.log(v)
  console.log('添加成功')
})

添加数据 多条添加

const User = mongoose.model('User', UserSchema)

// 定义数据
let arr = [
  { name: '小猪', age: 13, status: 0 },
  { name: '小明', age: 32, status: 1 },
  { name: '小红', age: 20, status: 1 },
  { name: '小赖', age: 22, status: 1 },
  { name: '小狗', age: 50, status: 1 },
  { name: '小力', age: 10, status: 0 }
]

// 使用 insertMany 插入多条数据
// doc 就是你添加成功之后给你返回的数据
User.insertMany(arr, (err, doc) => {
  if (err) return console.log(err)
  console.log('插入成功')
  console.log(doc)
})

// 方法2
let newArr = new Array()

arr.forEach((value, index) => {
  const info = new User(value)
  newArr.push(info)
})

User.insertMany(newArr, (err, doc) => {
  if (err) return console.log('数据添加失败')
  console.log(doc)
  console.log('数据添加成功')
})

修改数据

const User = mongoose.model('User', UserSchema)

// 把name的值是小四的字段里,age的值改成14
User.updateOne({
  'name': '小四'
}, {
  'age': 14
}, (err, res) => {
  if (err) return console.log('更新失败')
  console.log(res)
  console.log('更新成功')
})

删除数据

const User = mongoose.model('User', UserSchema)

// 删除一个status是0的
User.deleteOne({ status: 0 }, (err, doc) => {
  if (err) return console.log(err)
  console.log(doc)
})

// 删除所有 status是0的
User.deleteMany({ status: 0 }, (err, doc) => {
  if (err) return console.log(err)
  console.log(doc)
})

Getters与Setters 自定义修饰符

Getters:

const UserSchema = new mongoose.Schema({
  name: {
    type: String,
    get(params) {
      return '测试' + params
    }
  },
  age: Number,
  status: 'number'
})

const User = mongoose.model('User', UserSchema)
const newUser = new User({
  name: '小龙',
  age: 18,
  status: 1,
  url: 'https://www.baodu.com'
})
console.log(newUser.name)  // 测试小龙

Setters:

const UserSchema = new mongoose.Schema({
  name: {
    type: String
  },
  age: Number,
  status: 'number',
  url: {
    type: String,
    set(parmas) {
      if (!parmas) return ''
      const isHttp = parmas.indexOf('http://')
      const isHttps = parmas.indexOf('https://')
      if (isHttp !== 0 && isHttps !== 0) return 'http://' + parmas
      return parmas
    }
  }
})

const User = mongoose.model('User', UserSchema)
const newUser = new User({
  name: '小龙',
  age: 18,
  status: 1,
  url: 'www.baodu.com'
})
console.log(newUser)
/*
{
  name: '小龙',
  age: 18,
  status: 1,
  url: 'http://www.baodu.com',
  _id: new ObjectId("61fb5217081f1e60d8711b0e")
}
*/

mongoose 索引

索引是对数据库表中一列或多列的值进行排序的一种结构,可以让我们查询数据库变得更快。MongoDB 的索引几乎与传统的关系型数据库一模一样,这其中也包括一些基本的查询优化技巧。

mongoose 中除了以前创建索引的方式,我们也可以在定义Schema的时候指定创建索引

const DeviceSchema = new mongoose.Schema({
  sn: {
	type: String,
	//唯一索引
	unique: true
  },
  name: {
	type: String,
	// 普通索引
	index: true
  }
})

Model 的静态方法和实例方法

静态方法

const UserSchema = new mongoose.Schema({
  name: String,
  age: Number,
  status: 'number'
})


// 封装静态查询方法
UserSchema.statics.findByAge = function(age, callback) {
  this.find({age}, (err, docs) => {
    callback(err, docs)
  })
}

const User = mongoose.model('User', UserSchema)

User.findByAge('30', (err, res) => {
  if (err) return console.log(err)
  console.log(res)
})

实例方法 (基本不用)

const UserSchema = new mongoose.Schema({
  name: String,
  age: Number,
  status: 'number'
})

// 实例方法
UserSchema.methods.print = function() {
  console.log(this)
}

const User = mongoose.model('User', UserSchema)

const user = new User({
  name: '小刘',
  age: 18,
  status: 1
})

user.print()
/*
{
  name: '小刘',
  age: 18,
  status: 1,
  _id: new ObjectId("61fb6b16f14ac45e7d3d9b25")
}
*/

Mongoose 数据校验

mongoose数据校验是指用户通过mongoose给mongodb数据库增加数据的时候,对数据的合法性进行的验证。

在mongoose里面定义Schema的时候,通过设置字段类型,修饰符、默认参数 、数据校验等都是为了数据库数据的一致性。

校验参数

属性方法说明
require表示这个数据必须传入
max用于Number类型数据,最大值
min用于Number类型数据,最小值
enum枚举类型,要求数据必须满足枚举值 enum: [‘0’, ‘1’, ‘2’]
match增加的数据必须符合 match (正则) 的规则
maxlength最大值
minlength最小值
validate(v)自定义验证
trim去除两边的空格
const UserSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,    // 必须传入
    trim: true,		   // 修饰符 去除两边空格
    maxlength: 8,      // 最大8位
    minlength: 2,      // 最小2位
  },
  age: {
    type: Number,
    max: 100,          // 最大值是100
    min: 8             // 最小值是8
  },
  status: {
    type: Number,
    enum: [0, 1]      // 只能传入0和1
  },
  url: {
    type: String,
    match: /^http:\/\/(.*)/i
  }
})

const User = mongoose.model('User', UserSchema)

const user = new User({
  name: 'zss',
  age: 12,
  status: 0,
  url: 'http://'
})
user.save()
/*
  name值为空
  UnhandledPromiseRejectionWarning: ValidationError: User validation failed: name: Path `name` is required.\
*/

/* 
  name长度小于2
  UnhandledPromiseRejectionWarning: ValidationError: User validation failed: name: Path `name` (`z`) is shorter than the minimum allowed length (2).
*/

/*
  name长度大于8
  UnhandledPromiseRejectionWarning: ValidationError: User validation failed: name: Path `name` (`zsdsadsadas`) is longer than the maximum allowed length (8).
*/

/*
  status只能传入0和1
  UnhandledPromiseRejectionWarning: ValidationError: User validation failed: status: `50` is not a valid enum value for path `status`.
*/

/*
  age最大值是100,最小值是8
  UnhandledPromiseRejectionWarning: ValidationError: User validation failed: age: Path `age` (102) is more than maximum allowed value (100).
*/

/*
  url必须以http://开头
  UnhandledPromiseRejectionWarning: ValidationError: User validation failed: url: Path `url` is invalid (http:/).
*/

自定义校验

const UserSchema = new mongoose.Schema({
  num: {
    type: Number,
    validate(value) {
      return value % 2 === 0
    }
  }
})

const User = mongoose.model('User', UserSchema)

const user = new User({
  num: 7
})
user.save()

/*
  num 必须是偶数
  UnhandledPromiseRejectionWarning: ValidationError: User validation failed: num: Validator failed for path `num` with value `7`
*/

Mongoose 中使用 aggregate 聚合管道

$ne:表示not equals 就是不等于的意思

查询某字段不为空的数据
db.user.find({fieldName: {$ne:null}})

查询字段等于空的数据
db.user.find({fieldName: {$eq:null}})

$exists:表示是否存在。值为false表示不存在,值为true表示存在

查询某字段不为空的数据
db.user.find({fieldName:{$exists:true}})

查询某字段不存在的数据
db.user.find({fieldName:{$exists:false}})

mongoose中获取ObjectID

引入 mongoose 使用 mongoose.Types.ObjectId('xczxcxzczxcz3234')

const User = mongoose.model('User', UserSchema)

User.aggregate([
  {
    $lookup: {
      from: 'phones',
      localField: 'phone_id',
      foreignField: '_id',
      as: 'user_phone'
    }
  },
  {
    $match: {
      'phone_id': { $exists: true }
    }
  }
], (err, docs) => {
  console.log(docs)
})

多表关联查询

/*
	from: user	这是要关联 user 表
	localField  这是要跟 article 表里的 classify_id 字段进行关联
	foreignField 这是要跟 user 表里的 _id字段进行关联
	as			 这是别名,就是给这个新的数据起个名
*/

const { Article } = require('./db')
// 要关联多个表就继续往下写 { $lookup: {...} }
Article.aggregate([
  {
    $lookup: {
      from: 'articlecate',
      localField: 'classify_id',
      foreignField: '_id',
      as: 'cate'
    }
  },
  {
    $lookup: {
      from: 'user',
      localField: 'author_id',
      foreignField: '_id',
      as: 'user'
    }
  }
], (err, docs) => {
  console.log(JSON.stringify(docs))
})

多表关联查询结果

[
	{
		// 这个是article表
		"_id": "61fb9de67d8a21e93c2eaad2",
		"title": "第一个科技文章",
		"classify_id": "61fb9619215153325d17a193",
		"author_id": "61fb9bdee12c49d0f430d216",
		"author_name": "张三",
		"description": "这是张三发布的第一个科技文章,属于科技分类",
		"content": "这是科技 文章的内容,此处省略一万字",
		"__v": 0,
		// article表 关联了 articlecate表 并且起名叫cate
		"cate": [{
			"_id": "61fb9619215153325d17a193",
			"title": "科技新闻",
			"description": "科技新闻的描述。。。",
			"__v": 0
		}],
		// article表 关联了 user表 并且起名叫user
		"user": [{
			"_id": "61fb9bdee12c49d0f430d216",
			"username": "zhangsan",
			"password": "123456",
			"name": "张三",
			"age": 18,
			"sex": "男",
			"tel": 14895466411,
			"__v": 0
		}]
	},

	{
		"_id": "61fb9de67d8a21e93c2eaad3",
		"title": "第二个科技文章",
		"classify_id": "61fb9619215153325d17a193",
		"author_id": "61fb9bdee12c49d0f430d216",
		"author_name": "张三",
		"description": "这是张三发布的第二个科技文章,属于科技分类",
		"content": "这是科技文章的内容,此处省略一万字",
		"__v": 0,
		"cate": [{
			"_id": "61fb9619215153325d17a193",
			"title": "科技新闻",
			"description": "科技新闻的描述。。。",
			"__v": 0
		}],
		"user": [{
			"_id": "61fb9bdee12c49d0f430d216",
			"username": "zhangsan",
			"password": "123456",
			"name": "张三",
			"age": 18,
			"sex": "男",
			"tel": 14895466411,
			"__v": 0
		}]
	},

	{
		"_id": "61fb9de67d8a21e93c2eaad4",
		"title": "第一个金融文章",
		"classify_id": "61fb96563188bc6d398ed013",
		"author_id": "61fb9bdee12c49d0f430d216",
		"author_name": "张三",
		"description": "这是张三发布的第一个金融文章,属于金融分类",
		"content": "这是金融文章的内容,此处省略一万字",
		"__v": 0,
		"cate": [{
			"_id": "61fb96563188bc6d398ed013",
			"title": "金融新闻",
			"description": "金融新闻的描述。。。",
			"__v": 0
		}],
		"user": [{
			"_id": "61fb9bdee12c49d0f430d216",
			"username": "zhangsan",
			"password": "123456",
			"name": "张三",
			"age": 18,
			"sex": "男",
			"tel": 14895466411,
			"__v": 0
		}]
	}
]

多表查询 populate

//Article表

 // 分类ID
  classify_id: {
    type: mongoose.Types.ObjectId,
    ref: 'ArticleCate'  // 关联的Model
  },
  // 作者ID
  author_id: {
    type: mongoose.Types.ObjectId,
    ref: 'User'
  },
// app.js

const { Article } = require('./db')

// populate('classify_id')   需要关联的字段
Article.find({}).populate('classify_id').populate('author_id').exec((err, docs) => {
  console.log(docs)
})

这是返回的数据,这里不能起别名,直接就覆盖字段了

  {
    _id: new ObjectId("61fb9e5735882d989cf8833a"),
    title: '第二个美食文章(小红)',
    classify_id: {
      _id: new ObjectId("61fb9645c342558ade4e1f3c"),
      title: '美食新闻',
      description: '美食新闻的描述。。。',
      __v: 0
    },
    author_id: {
      _id: new ObjectId("61fb9bdee12c49d0f430d219"),
      username: 'xiaohong',
      password: '123456',
      name: '小红',
      age: 18,
      sex: '女',
      tel: 15478932000,
      __v: 0
    },
    author_name: '小红',
    description: '这是小红发布的第二个美食文章,属于美食分类',
    content: '这是美食文章的内容,此处省略一万字',
    __v: 0
  }

性能还是推荐使用 aggregate

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
1. 安装mongoose 在命令行执行以下命令: ``` npm install mongoose ``` 2. 连接数据库Node.js使用mongoose连接数据库需要先引入mongoose模块: ```javascript const mongoose = require('mongoose') ``` 接着使用mongoose.connect()方法连接数据库: ```javascript mongoose.connect('mongodb://localhost:27017/databaseName', { useNewUrlParser: true }) ``` 其mongodb://localhost:27017/databaseName是连接数据库的URL,其localhost为数据库服务器地址,27017为MongoDB的默认端口号,databaseName为要连接数据库名称。 { useNewUrlParser: true }是Mongoose的一个选项,以允许在连接使用新的URL字符串解析器。 3. 定义Schema和Model 在使用mongoose之前,需要先定义Schema和Model。Schema是用来定义数据结构的,Model是由Schema生成的实例。 ```javascript const Schema = mongoose.Schema const userSchema = new Schema({ username: String, password: String, email: String }) const User = mongoose.model('User', userSchema) ``` 以上代码定义了一个名为User的Model,该Model对应的Schema定义了三个属性:username、password和email。 4. CRUD操作 通过定义好的Model可以进行CRUD操作。以下是一些常用的操作: - 新增数据 ```javascript const user = new User({ username: 'Tom', password: '123456', email: 'tom@example.com' }) user.save(function (err, user) { if (err) return console.error(err) console.log(user.username + ' saved to database.') }) ``` - 查询数据 ```javascript User.find(function (err, users) { if (err) return console.error(err) console.log(users) }) ``` - 更新数据 ```javascript User.findOneAndUpdate({ username: 'Tom' }, { password: '654321' }, function (err, user) { if (err) return console.error(err) console.log(user) }) ``` - 删除数据 ```javascript User.deleteOne({ username: 'Tom' }, function (err) { if (err) return console.error(err) console.log('User deleted.') }) ``` 以上代码演示了如何使用mongoose连接MongoDB数据库,并进行CRUD操作。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值