Node.js 手册查询-Mongoose 方法
一、Schema
一种以文件形式存储的数据库模型骨架,无法直接通往数据库端,也就是说它不具备对数据库的操作能力.可以说是数据属性模型(传统意义的表结构),又或着是“集合”的模型骨架
/* 定义一个 Schema */ var mongoose = require("mongoose"); var TestSchema = new mongoose.Schema({ name : { type:String },//属性name,类型为String age : { type:Number, default:0 },//属性age,类型为Number,默认为0 time : { type:Date, default:Date.now }, email: { type:String,default:''} });
上面这个 TestSchema包含4个属性 [name, age, time, email]
二、Model
由Schema构造生成的模型,除了Schema定义的数据库骨架以外,还具有数据库操作的行为,类似于管理数据库属性、行为的类
var db = mongoose.connect("mongodb://127.0.0.1:27017/test"); // 创建Model var TestModel = db.model("test1", TestSchema);
test1 数据库中的集合名称, 不存在会创建.
model - 文档操作
mongoose的操作方法基本都在文档操作中。
1.构造函数, 参数1:集合名称, 参数2:Schema实例
db.model(“test1”, TestSchema );
2.查询, 参数1忽略,或为空对象则返回所有集合文档
model.find({}, callback); model.find({},field,callback); 过滤查询,参数2: {‘name’:1, ‘age’:0} 查询文档的返回结果包含name , 不包含age.(_id默认是1) model.find({},null,{limit:20}); 过滤查询,参数3: 游标操作 limit限制返回结果数量为20个,如不足20个则返回所有. model.findOne({}, callback); 查询找到的第一个文档 model.findById(‘obj._id’, callback); 查询找到的第一个文档,同上. 但是只接受 __id 的值查询
3.创建, 在集合中创建一个文档
Model.create(文档数据, callback))
4.更新,参数1:查询条件, 参数2:更新对象,可以使用MondoDB的更新修改器
Model.update(conditions, update, function(error)
5.删除, 参数1:查询条件
Model.remove(conditions,callback);
更新修改器:
6.‘$inc’ 增减修改器,只对数字有效.下面的实例: 找到 age=22的文档,修改文档的age值自增1
Model.update({‘age’:22}, {’$inc’:{‘age’:1} } ); 执行后: age=23
7.‘$set’ 指定一个键的值,这个键不存在就创建它.可以是任何MondoDB支持的类型.
Model.update({‘age’:22}, {’$set’:{‘age’:‘haha’} } ); 执行后: age=‘haha’
8.‘$unset’ 同上取反,删除一个键
Model.update({‘age’:22}, {’$unset’:{‘age’:‘haha’} } ); 执行后: age键不存在
数组修改器:
9.‘$push’ 给一个键push一个数组成员,键不存在会创建
Model.update({‘age’:22}, {’$push’:{‘array’:10} } ); 执行后: 增加一个 array 键,类型为数组, 有一个成员 10
10.‘$addToSet’ 向数组中添加一个元素,如果存在就不添加
Model.update({‘age’:22}, {’$addToSet’:{‘array’:10} } ); 执行后: array中有10所以不会添加
11. ‘$each’ 遍历数组, 和 $push 修改器配合可以插入多个值
Model.update({‘age’:22}, {’$push’:{‘array’:{’$each’: [1,2,3,4,5]}} } ); 执行后: array : [10,1,2,3,4,5]
12.‘$pop’ 向数组中尾部删除一个元素
Model.update({‘age’:22}, {’$pop’:{‘array’:1} } ); 执行后: array : [10,1,2,3,4] tips: 将1改成-1可以删除数组首部元素
13.‘$pull’ 向数组中删除指定元素
Model.update({‘age’:22}, {’$pull’:{‘array’:10} } ); 执行后: array : [1,2,3,4] 匹配到array中的10后将其删除
条件查询:
a. “$lt” 小于
b. “$lte” 小于等于
c. “$gt” 大于
d. “$gte” 大于等于
e. “$ne” 不等于
params = { salePrice:{ $gt: priceGt, $lte: priceLt } } let goodsModel = Goods.find(params)
或查询 OR:
- ‘$in’ 一个键对应多个值
- ‘$nin’ 同上取反, 一个键不对应指定值
- “$or” 多个条件匹配, 可以嵌套 $in 使用
- “$not” 同上取反, 查询与特定模式不匹配的文档
Model.find({“age”:{ “$in”:[20,21,22.‘haha’]} } ); 查询 age等于20或21或21或’haha’的文档 Model.find({"$or" : [ {‘age’:18} , {‘name’:‘xueyou’} ] }); 查询 age等于18 或 name等于’xueyou’ 的文档
类型查询:
null 能匹配自身和不存在的值, 想要匹配键的值 为null, 就要通过 “$exists” 条件判定键值已经存在 "$exists" (表示是否存在的意思)
-
Model.find(“age” : { “$in” : [null] , “exists” : true } ); 查询 age值为null的文档
Model.find({name: {$exists: true}},function(error,docs){ //查询所有存在name属性的文档 }); Model.find({telephone: {$exists: false}},function(error,docs){ //查询所有不存在telephone属性的文档 });
正则表达式:
MongoDb 使用 Prel兼容的正则表达式库来匹配正则表达式
find( {“name” : /joe/i } ) 查询name为 joe 的文档, 并忽略大小写 find( {“name” : /joe?/i } ) 查询匹配各种大小写组合
查询数组:
Model.find({“array”:10} ); 查询 array(数组类型)键中有10的文档, array : [1,2,3,4,5,10] 会匹配到 Model.find({“array[5]”:10} ); 查询 array(数组类型)键中下标5对应的值是10, array : [1,2,3,4,5,10] 会匹配到
$all’ 匹配数组中多个元素
Model.find({“array”:[5,10]} ); 查询 匹配array数组中 既有5又有10的文档
‘$size’ 匹配数组长度
Model.find({“array”:{"$size" : 3} } ); 查询 匹配array数组长度为3 的文档
‘$slice’ 查询子集合返回
Model.find({“array”:{"$skice" : 10} } ); 查询 匹配array数组的前10个元素 Model.find({“array”:{"$skice" : [5,10] } } ); 查询 匹配array数组的第5个到第10个元素
常用方法:
1、删除购物车
/** * 购物车删除 */ router.post('/cart/del', function(req, res, next) { var userId = req.cookies.userId, productId = req.body.productId; User.update({ userId: userId // 根据 ID 找到相对应的数据库数据 },{ $pull:{ // 删除特定元素 'cartlist': { // 找到 相对的cartlist 根据 productId 删除相对应的 数据 'productId': productId } } }, (err, doc) => { if(err){ res.json({ status: "1", msg: err.message, result: '' }); }else{ res.json({ status: "0", msg: '', result: doc }); } }); });
2、购物车数量修改
/** * 购物车数量修改 */ router.post('/cart/edit', function(req, res, next) { var userId = req.cookies.userId, productId = req.body.productId, productNum = req.body.productNum; // 根据 userId 先找到这个用户数据,再找到跟传递过来的 productId 相对应的 cartlist 里面的那个商品数据,第一步是查找数据 // 这个不找找的是就是子数据,不是 productNum 相对应的那个商品 json User.update({ "userId": userId, "cartlist.productId": productId },{ // 找到那个数据之后 利用这个方法更改数量 'cartlist.$.productNum': productNum }, (err, doc) => { if(err){ res.json({ status: "1", msg: err.message, result: '' }); }else{ res.json({ status: "0", msg: '', result: 'suc' }); } }); });
3、新增地址(向数据库新添加数据)
router.post('/addNewAddress', (req, res, next) => { var userId = req.cookies.userId, addressName = req.body.addressName, tel = parseFloat(req.body.tel), streetName = req.body.streetName, postCode = req.body.postCode; User.findOne({userId: userId}, (err, doc) => { if(err){ res.json({ status: "1", msg: err.message, result: '' }); }else{ if(doc){ var addressList = doc.addressList, num = parseInt(addressList.length) - 1, addressId = addressList[num].addressId, addressNewId = ''; addressNewId = parseInt(addressId) + 1; var jsonNew = { addressId: addressNewId, addressName: addressName, tel: tel, streetName: streetName, postCode: postCode }; // 将新建的json数据直接push到以前的数组中,然后保存就可以了 addressList.push(jsonNew); doc.save((err1, doc1) => { if(err1){ res.json({ status: "1", msg: err1.message, result: '' }); }else{ res.json({ status: "0", msg: '', result: 'suc' }); } }); } } }); });
4、查看所有地址(查)
/** * addressList */ router.get('/addressList', function(req, res, next) { var userId = req.cookies.userId; User.findOne({userId: userId}, (err, doc) => { if(err){ res.json({ status: "1", msg: err.message, result: '' }); }else{ if(doc){ res.json({ status: "0", msg: '', result: doc.addressList }); } } }); });