Mongoose 是什么?
一般我们不直接用MongoDB的函数来操作MongoDB数据库 Mongose就是一套操作MongoDB数据库的接口.
Schema
一种以文件形式存储的数据库模型骨架,无法直接通往数据库端,也就是说它不具备对数据库的操作能力.可以说是数据属性模型(传统意义的表结构),又或着是”集合”的模型骨架
1 2 3 4 5 6 7 8 9
| var mongoose = require("mongoose");
var TestSchema = new mongoose.Schema({ name : { type: String }, age : { type: Number, default: 0 }, time : { type: Date, default: Date.now }, email: { type: String,default: ''} });
|
上面这个 TestSchema包含4个属性 [name, age, time, email]
Model
由Schema构造生成的模型,除了Schema定义的数据库骨架以外,还具有数据库操作的行为,类似于管理数据库属性、行为的类
1 2 3 4
| var db = mongoose.connect("mongodb://127.0.0.1:27017/test");
var TestModel = db.model("test1", TestSchema);
|
test1 数据库中的集合名称, 不存在会创建.
Entity
由Model创建的实体,使用save方法保存数据,Model和Entity都有能影响数据库的操作,但Model比Entity更具操作性
1 2 3 4 5 6 7
| var TestEntity = new TestModel({ name : "Lenka", age : 36, email: "lenka@qq.com" }); console.log(TestEntity.name); console.log(TestEntity.age);
|
游标
MongoDB 使用游标返回find的执行结果.客户端对游标的实现通常能够对最终结果进行有效的控制。可以限制结果的数量,略过部分结果,根据任意键按任意顺序的组合对结果进行各种排序,或者是执行其他一些强的操作。
ObjectId
存储在mongodb集合中的每个文档(document)都有一个默认的主键_id,这个主键名称是固定的,它可以是mongodb支持的任何数据类型,默认是ObjectId。
ObjectId是一个12字节的 BSON 类型字符串。按照字节顺序,依次代表:
- 4字节:UNIX时间戳
- 3字节:表示运行MongoDB的机器
- 2字节:表示生成此_id的进程
- 3字节:由一个随机数开始的计数器生成的值
Node.js 中
package.json 中加入”mongoose”: “*“ 字段
npm install 安装依赖.
1 2
| var mongoose = require("mongoose"); mongoose.connect("mongodb://localhost:27017/test");
|
然后引用
1 2 3 4
| mongoose.on('error',console.error.bind(console,'连接错误:')); mongoose.once('open',function(){ });
|
db - 数据库操作
挂接数据库连接事件,参数1: 也可以是error.
1
| mongoose.connection.on('open', callback);
|
Schema - 表结构
1.构造函数
1 2 3
| var PersonSchema = new mongoose.Schema({ name:String });
|
2.添加属性
1 2 3 4 5
| Schema.add({ name: 'String', email: 'String', age: 'Number' })
|
3.有时候Schema不仅要为后面的Model和Entity提供公共的属性,还要提供公共的方法
1 2 3 4
| Schema.method('say', function() { console.log('hello'); })
|
4.添加静态方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| Schema.static('say', function() { console.log('hello'); })
Schema.statics = { fetch: function(cb) { return this .find({}) .sort('meta.updateAt') .exec(cb) },
findById: function(id, cb) { return this .findOne({ _id: id }) .exec(cb) } }
|
5.追加方法
1 2 3 4
| Schema.methods.say = function() { console.log('hello'); };
|
model - 文档操作
1.构造函数, 参数1:集合名称, 参数2:Schema实例
1 2 3 4
| var PersonModel = mongoose.model('Person',PersonSchema);
|
2.查询, 参数1忽略,或为空对象则返回所有集合文档
1
| model.find({}, callback);
|
1 2
| model.find({},field,callback);
|
1 2
| model.find({},null,{limit:20},callback);
|
1 2
| model.findOne({}, callback);
|
1 2
| model.findById('obj._id', callback);
|
3.创建, 在集合中创建一个文档
1
| Model.create(文档数据, callback))
|
4.更新,参数1:查询条件, 参数2:更新对象,可以使用MondoDB的更新修改器
1
| Model.update(conditions, update, function(error){})
|
5.删除, 参数1:查询条件
1
| Model.remove(conditions,callback);
|
Entity - 文档操作
1.构造函数, 其实就是model的实例
1
| new TestModel( { name:'xueyou', age:21 } );
|
2.创建, 在集合中创建一个文档.
更新修改器
‘$inc’增减修改器,只对数字有效.下面的实例: 找到 age=22的文档,修改文档的age值自增1
1 2 3 4 5 6 7 8
| Model.update({ 'age': 22 }, { '$inc': { 'age': 1 } }); 执行后: age=23
|
‘$set’ 指定一个键的值,这个键不存在就创建它.可以是任何MondoDB支持的类型.
1 2 3 4 5 6 7 8
| Model.update({ 'age': 22 }, { '$set': { 'age': 'haha' } }); 执行后: age='haha'
|
‘$unset’ 同上取反,删除一个键
1 2 3 4 5 6 7 8
| Model.update({ 'age': 22 }, { '$unset': { 'age': 'haha' } }); 执行后: age键不存在
|
数组修改器:
‘$push’ 给一个键push一个数组成员,键不存在会创建
1 2 3 4 5 6 7 8
| Model.update({ 'age': 22 }, { '$push': { 'array': 10 } }); 执行后: 增加一个 array 键,类型为数组, 有一个成员 10
|
‘$addToSet’ 向数组中添加一个元素,如果存在就不添加
1 2 3 4 5 6 7 8
| Model.update({ 'age': 22 }, { '$addToSet': { 'array': 10 } }); 执行后: array中有10所以不会添加
|
‘$each’ 遍历数组, 和 $push 修改器配合可以插入多个值
1 2 3 4 5 6 7 8 9 10
| Model.update({ 'age': 22 }, { '$push': { 'array': { '$each': [1, 2, 3, 4, 5] } } }); 执行后: array : [10,1,2,3,4,5]
|
‘$pop’ 向数组中尾部删除一个元素
1 2 3 4 5 6 7 8
| Model.update({ 'age': 22 }, { '$pop': { 'array': 1 } }); 执行后: array : [10,1,2,3,4] tips: 将1改成-1可以删除数组首部元素
|
‘$pull’ 向数组中删除指定元素
1 2 3 4 5 6 7 8
| Model.update({ 'age': 22 }, { '$pull': { 'array': 10 } }); 执行后: array : [1,2,3,4] 匹配到array中的10后将其删除
|
条件查询:
- “$lt” 小于
- “$lte” 小于等于
- “$gt” 大于
- “$gte” 大于等于
- “$ne” 不等于
1 2 3 4 5 6 7
| Model.find({ "age": { "$gte": 18, "$lte": 30 } });
|
或查询 OR:
- ‘$in’ 一个键对应多个值
- ‘$nin’ 同上取反, 一个键不对应指定值
- “$or” 多个条件匹配, 可以嵌套 $in 使用
- “$not” 同上取反, 查询与特定模式不匹配的文档
1 2 3 4 5 6
| Model.find({ "age": { "$in": [20, 21, 22.' haha'] } });
|
1 2 3 4 5 6 7 8
| Model.find({ "$or": [{ "age": 18 }, { "name": "xueyou" }] });
|
类型查询:
null 能匹配自身和不存在的值, 想要匹配键的值 为null, 就要通过 “$exists” 条件判定键值已经存在
“$exists” (表示是否存在的意思)
1 2 3 4 5
| Model.find("age": { "$in": [null], "exists": true });
|
1 2 3 4 5 6 7
| Model.find({ name: { $exists: true } }, function(error, docs) {
});
|
1 2 3 4 5 6 7
| Model.find({ telephone: { $exists: false } }, function(error, docs) {
});
|
正则表达式:
MongoDb 使用 Prel兼容的正则表达式库来匹配正则表达式
1 2 3 4
| find({ "name": /joe/i })
|
1 2 3 4
| find({ "name": /joe?/i })
|
查询数组:
1 2 3 4
| Model.find({ "array": 10 });
|
1 2 3 4
| Model.find({ "array[5]": 10 });
|
‘$all’ 匹配数组中多个元素
1 2 3 4
| Model.find({ "array": [5, 10] });
|
‘$size’ 匹配数组长度
1 2 3 4 5 6
| Model.find({ "array": { "$size": 3 } });
|
‘$slice’ 查询子集合返回
1 2 3 4 5 6
| Model.find({ "array": { "$skice": 10 } });
|
1 2 3 4 5 6
| Model.find({ "array": { "$skice": [5, 10] } });
|
where
用它可以执行任意javacript语句作为查询的一部分,如果回调函数返回 true 文档就作为结果的一部分返回
1 2 3 4 5 6 7 8 9 10 11 12 13
| find({ "$where": function() { for (var x in this) { }
if (this.x !== null && this.y !== null) { return this.x + this.y === 10 ? true : false; } else { return true; } } })
|
简化版本
1 2 3 4 5 6
| find({ "$where": "this.x + this.y === 10" }) find({ "$where": " function(){ return this.x + this.y ===10; } " })
|
游标:
- limit(3) 限制返回结果的数量,
- skip(3) 跳过前3个文档,返回其余的
- sort( {“username”:1 , “age”:-1 } ) 排序 键对应文档的键名, 值代表排序方向, 1 升序, -1降序
参考