概念
Schema - 数据库存储格式的约定协议,可以理解为数据表的字段类型声明
Model - 由Schema转化的数据模型,具有抽象属性和行为的数据库操作,可以进行查询操作
Entity - 由Model创建的实体,可以对数据库表进行完整的CRUD操作
Mongoose使用
一、安装
$ npm install mongoose
二、示例
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// 连接mongodb
mongoose.connect('mongodb://car:welcomeCar@localhost/myCar'); // mongodb://用户名:密码@数据库IP/库名
// 连接成功
mongoose.connection('connected', ()=>{
console.log('connect success');
})
// 连接失败
mongoose.connection('error', ()=>{
console.log('connect error' + err);
})
// 连接断开
mongoose.connection('disconnected', ()=>{
console.log('connect disconnected');
})
// 创建Schema
const UserSchema = new Schema({
username: String,
password: String,
age: Number,
LoginAt: Date
})
// 定义Model
const UserModel = mongoose.model('User', UserSchema);
// 插入数据
let userData = new UserModel({
username: 'siguang',
password: 'ssssss',
age: 20,
loginAt: new Date()
})
// 保存
userData.save((err, res)=>{
if(err){
return console.log(err)
}
console.log(res);
})
// 删除
userData.remove({age: 30}, (err, doc) => {
if(err){
return console.log(err)
}
console.log(doc);
})
// 查询
userData.find({username: 'siguang', (err, doc)=>{
if(err){
return console.log(err)
}
console.log(doc);
})
// 数量
userData.count({age: 20}, (err, doc)=>{
if(err){
return console.log(err)
}
console.log(doc);
})
连接
mongoose两种连接: connect连单个db并打开,createConnect连接多个db
一、mongoose.connect()方法连接
写法1:
connect('mongodb://[username]:[password]@host:port/database?options...'); // 用户名、密码、主机、端口、库名、参数
let db = mongoose.connect('mongodb://[username]:[password]@127.0.0.1:27017/myDB');
写法2:
-- conect(uri, options) --
var options = {
db: { native_parser: true },
server: { poolSize: 5 },
replset: { rs_name: 'myReplicaSetName' },
user: 'myUserName',
pass: 'myPassword'
}
var uri = 'mongodb://localhost/dbName?poolSize=4';
mongoose.connect(uri, options);
-- mongoose.createConnection() --
二、多个连接
let mongoose = require('mongoose');
let db = mongoose.connect('mongodb://127.0.0.1:27017/myDB'); // mongodb://IP:端口号/数据库名
// 侦听打开的回调
db.connection.on('error', function(error){
console.log('数据库连接失败'+error);
})
// 侦听连接成功
db.connection.on('open', function(){
console.log('连接成功')
})
三、两者的区别
var mongoose = require('mongoose');
db = mongoose.createConnection('localhost', 'test');
var schema = new mongoose.Schema({ name: String });
var collectionName = 'kittens';
var M = db.model('Kitten', schema, collectionName);
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
db = mongoose.connection;
db.once('open', function callback () {
// yay!
});
createConnection,可以open,但完全不会查询。第二种方法就可以
Schema
Schema: 一种文件形式存储数据库模型的骨架,无法直接连接数据端,不具备操作数据库的能力,叫数据属性模型或集合
一、定义表的文档结构
let personSchema = new mongoose.Schema({
name: String,
age: Number,
email: { type: String, max: 20 }
})
二、实例方法、静态方法
let PersonSchema = new mongoose.Schema({
name: String,
age: Number,
email: { type: String, max: 20 }
})
var Person = mongoose.model('person', PersonSchema);
var silence = new Person({ name: 'Silence' });
PersonSchema.methods.speak = function(){ }
三、index 索引
let Schema = mongoose.Schema;
let carSchema = new Schema({
name: String,
title: { type: String, index: true }, // index 索引
uid: { type: Number, unique: true }, // unique 独一无二的
date: { type: Date, default: Date.now } // default 默认值
})
// 文档索引和字段索引
let carSchema = new Schema({
name: String,
title: { type: [String], index: true }, // 字段索引
})
carSchema.index({ name: 1, type: -1}); //
Schema Type
https://xiaoxiami.gitbook.io/mongoose/guide/schemas/typesmd
一、类型
1、String:字符串
2、Number:数值
3、Date:日期
4、Buffer: 二进制
5、Boolean:布尔
6、Mixed: 混合
7、ObjectId: ObjectId
8、Array:数组
二、其它参数
default: 默认 // updated: { type: Date, default: Date.now }
min/max: 最小或最大 // age: { type: Number, min: 18, max: 65 }
trim: 去掉两端空格
lowercase: true // 保存前将字符转成小写
uppercase: true // 保存前将字符转成大写
required: true // 必填
match:RegExp // 创建一个正则验证器
enum:Array // 检查值是否在给定的数组中
index: true // 索引
unique: true // 索引,指定字段为独一无二
三、Example
var schema = new Schema({
idCard: { type: String, unique: true, trim: true }, // 用户id 字段独一无二、去掉两端空格
name: String, // 可以直接写成String,也可以写成 {type: String}
binary: Buffer,
living: Boolean,
updated: { type: Date, default: Date.now }
age: { type: Number, min: 18, max: 65 }
mixed: Schema.Types.Mixed,
_someId: Schema.Types.ObjectId,
array: [],
ofString: [String],
ofNumber: [Number],
ofDates: [Date],
ofBuffer: [Buffer],
ofBoolean: [Boolean],
ofMixed: [Schema.Types.Mixed],
ofObjectId: [Schema.Types.ObjectId],
nested: {
stuff: { type: String, lowercase: true, trim: true }
}
})
Model
具有操作数据库的能力,类似管理数据库的属性和行的类
创建model mongoose.model('集合名', schema);
let personScheam = new Scheam({
name: 'String',
password: 'String'
}, {
timestamps: true, // 设置timestamps,多加两个字段createdTime、updatedTime,来记录插入时间和更新时间
collection: 'report_warning_config',
})
let personModel = mongoose.model('person', personSchema);
查询
一、find, findById, findOne, or where
let TankScheam = new Scheam({
name: 'String',
password: 'String'
})
let Tank = mongoose.model('Tank', personSchema);
Tank.find({size: 'samll'}).where('createDate').gt(oneYear).exec(callback);
二、条件查询中常用属性
$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个元素
三、方法
1、where('price') - 查询的字段 Tank.find().where('price')
2、find() - 查询所有,返回的是数组
3、findOne({name: 'siguang'}) - 只把第一条name为siguang的数据,如果find会将所有都返回
4、findById(id) - 根据一条id来查找,返回的是一条记录的对象,而不是一个数组,与find({_id: '59bf7ee03f55167fb6cdd75c'})相同
5、findByIdAndRemove(id) - 根据id查找,并删除这个条数据,如果查找不到返回 null
6、findByIdAndUpdate(id, update) -
7、lean() - Tank.find().lean() // 默认参数为true, 可以设置 lean(false)
删除
Tank.remove({size: 'large'})
// 查找并删除
Tank.findByAndRemove()
更新
Tank.update({_id: id}, {$set: {size: 'large'}, callback);
// 查找并更新
Tank.findByIdAndUpdate(id, [update]);
Entity
save()
insert和update都需要save(),
egg-mongose 总结
1、问题描述:连接mongoose的过程中遇到mongodb collection自动加s,比如mongo库中有一个userTest集合,如果使用inser会新创建一个userTests
解决:在创建mode的时候要指定集合名
module.exports = app => {
const mongoose = app.mongoose;
const UserTestSchema = new mongoose.Schema({
idx: { type: Number },
password: { type: String }
});
return mongoose.model('userTest', UserTestSchema, 'userTest'); // 这里第三个参数要加
}
1、Model中创建模型
module.exports = app => {
const mongoose = app.mongoose;
const NewsSchema = new mongoose.Schema({
newsId: { type: Number },
newsTitle: {type: String, max: 32},
newsContent: {type: String},
},{
timestamps: true, // 插入记录时会自动创建一个createAt和updateAt时间字段
collection: 'news', // mongo中存的collection名
});
NewsSchema.index({ 'newsId': 1 }); // newsId为索引
return mongoose.model('News', NewsSchema); // News调用时的名
}
2、在service中调用
let doc = await app.model.News.find();
3、创建和查询
const doc = await new app.model.User(user).save(); // 创建时需要new
const user = await app.model.User.findOne({_id: user._id}); // 查询时不需要new
4、使用find()查询
如果使用find().lean()返回的是纯javascript对象,而不是mongoose文档,他们没有保存方法
const resourceTree = await app.model.Resource.find({});
const resourceTree = await app.model.Resource.find({}).lean();
返回
[
{ _id: 5a535142fe6d170e82135e89,
displayName: '欢欢',
username: 'huanhuan',
mobile: 13012309874,
email: 'huan@126.com'
},
{ _id: 5a5357d2bd53b40f791362aa,
username: 'maolv',
displayName: '毛驴',
mobile: 13290984585,
email: 'maolv@126.com'
}
]
5、查询条件写法lt
const password = app.model.UserTest.find().where('idx').lt(5); // 返回idx字段中小于5的条数
6、更新
async addChannel(params) {
const channel = await app.model.ConfigBusinessChannel.findOne({ businessType: params.businessType });
if (channel) {
return app.renderBody({
statusType: app.statusType.recordAlreadyExisted,
});
}
const channelModel = new app.model.ConfigBusinessChannel({
businessType: params.businessType, // 业务渠道ID
businessName: params.businessName, // 业务渠道名
isEnabled: params.isEnabled, // 是否启用
paySignedCompanys: [], // 签约的结算主体
});
await channelModel.save();
const response = app.renderBody({
statusType: app.statusType.success,
data: {},
});
return response;
}
| https://mongoose.shujuwajue.com/guide/schemas.html // 中文API
| http://www.nodeclass.com/api/mongoose.html
| https://github.com/eggjs/egg-mongoose egg-mongoose
| http://cnodejs.org/topic/504b4924e2b84515770103dd
| http://www.cnblogs.com/xuange306/p/4603551.html
| http://www.cnblogs.com/winyh/p/6682039.html
| http://cnodejs.org/topic/504b4924e2b84515770103dd
| http://www.hubwiz.com/class/543b2e7788dba02718b5a4bd