mongoose
查詢過濾
const results = await User.find({
"$and": [{
"date": {
"$gt": "2019-11-26 14:19:31"
}
}, {
"date": {
"$lt": "2019-11-26 14:52:15"
}
}]
}, 'uid age')
查詢條件date是2019-11-26 14:19:31 到 2019-11-26 14:52:15 區間的值(小於等於是$lte 大於等於是$gte) 並且返回uid age字段其餘不返回(findOne,findById類似)
mongoose常用操作(你當然也可以用原生的mongodb 不過沒必要重複造輪子)
models = 》 User
import mongoose from 'mongoose';
const Schema = mongoose.Schema
const UserSchema = new Schema({
uid: {
type: Number,
unique: true,
index: true
},
user: {
type: String,
unique: true,
index: true
},
password: String,
status: {
type: Boolean,
default: true
}
})
export default mongoose.model('User', UserSchema)
user.js
let result = []
//Model.find(query, fields, options, callback)
result = await User.find()//返回User的全部數據
result = await User.find({
user: 'zhang',
password: '123456'
}, { _id: 0, __v: 0, password: 0 },function(err.doc){console.log(doc)})//返回User中user爲'zhang',password爲'123456' 並且返回的結果中除去_id _v password鍵名的全部數據 docs 是查詢的結果數組
findOne是隻返回一個結果即第一個
findById是根據id查詢
User.findById(obj._id, function (err, doc){
// doc 是單個文檔
});
await User.find(}, function(err, doc) { }).count() //符合條件的總數
result = await User.find({}, { _id: 0 ,password:0}) //過濾_id password
// .where('level').gte(6) //level的值得大於等於6
.where({
'level': {
$gt: 3,
$lt: 6
},
'user': /zhang/, //模糊搜索zhang
})//level的值得:3<level<6
.skip(0 * 5) //skip是分頁 參數格式是 pageNo*pageSize
.limit(5) //limit是顯示幾個 參數 pageSize
.sort({ 'uid': -1 }) //uid大小排序
methods方法 statics 靜態方法
var animalSchema = new Schema({ name: String, type: String });
animalSchema.methods.findSimilarTypes = function(cb) {
return this.model("Animal").findOne({ type: 'dog' }, cb);
};
animalSchema.statics.findByName = function(cb) {
return this.model("Animal").findOne({ type: 'dog' }, cb);
};
var Animal = mongoose.model('Animal', animalSchema);
var dog = new Animal({ type: 'dog' });
// // dog.save()
dog.findSimilarTypes(function(err, dogs) {
console.log(dogs.type); // dog
});
Animal.findByName(function(err, dogs) {
console.log(dogs.type);
});
分頁查詢
數據格式
[{
_id: 5ddde8a2ea18323164978d2a,
user: 'zhang10',
uid: 10,
email: '',
date: '2019-11-27 11:08:18',
level: 1
}]
router.post('/queryUsers', async(ctx) => {
let query = { }
let pageSize = 10
let pageNo = 1
let levelList = []
let level1 = 0,
level2 = 0,
level3 = 0,
level4 = 0,
level5 = 0,
level6 = 0
if (ctx.request.body.pageSize) {
pageSize = ctx.request.body.pageSize
}
if (ctx.request.body.pageNo) {
pageNo = ctx.request.body.pageNo
}
if ((ctx.request.body.startDate && ctx.request.body.endDate)) {
// pageNo = 1
let q = query["$and"] ? query["$and"] : ''
query["$and"] = [...q, {
"date": {
"$gt": ctx.request.body.startDate
}
}, {
"date": {
"$lt": ctx.request.body.endDate
}
}]
}
if (ctx.request.body.searchName) {
// pageNo = 1
let q = query["$and"] ? query["$and"] : ''
query["$and"] = [...q, {
// "user": `zhang` 具體搜索
"user": {
$regex: ctx.request.body.searchName,
$options: '$i'
}
}]
}
if (ctx.request.body.authority) {
// pageNo = 1
let q = query["$and"] ? query["$and"] : ''
query["$and"] = [...q, {
"level": ctx.request.body.authority // 具體搜索
}]
}
const results = await User.find(query, 'user uid level date email')
.skip((pageNo - 1) * pageSize)
.limit(Number(pageSize))
const total = await User.find(query).count()
// const total = results.length
level1 = await User.find(query).where({ "level": 1 }).skip((pageNo - 1) * pageSize)
.limit(Number(pageSize)).count()
level2 = await User.find(query).where({ "level": 2 }).skip((pageNo - 1) * pageSize)
.limit(Number(pageSize)).count()
level3 = await User.find(query).where({ "level": 3 }).skip((pageNo - 1) * pageSize)
.limit(Number(pageSize)).count()
level4 = await User.find(query).where({ "level": 4 }).skip((pageNo - 1) * pageSize)
.limit(Number(pageSize)).count()
level5 = await User.find(query).where({ "level": 5 }).skip((pageNo - 1) * pageSize)
.limit(Number(pageSize)).count()
level6 = await User.find(query).where({ "level": 6 }).skip((pageNo - 1) * pageSize)
.limit(Number(pageSize)).count()
levelList = [
["level1", level1],
["level2", level2],
["level3", level3],
["level4", level4],
["level5", level5],
["level6", level6]
]
console.log(results)
console.log(results.length)
console.log(total)
try {
ctx.body = {
code: 200,
msg: '請求成功',
data: {
result: results ? results : [],
levelList: levelList ? levelList : [],
total: total ? total : 0
}
}
} catch (error) {
}
})
$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個元素
koa
koa2參數獲取
get 在請求參數裏
ctx.request.query.name;
post 在請求體裏
ctx.request.body.name;
獲取參數以及設置默認值
post const { pageSize = 10, pageNo = 1, user, password } = ctx.request.body
get const { pageSize = 10, pageNo = 1, user, password } = ctx.request.query
{
user:'zhang'
}
console.log(pageSize, pageNo, user, password)
// 10 1 zhang undefined
未傳參的處理
if (password == undefined) {
ctx.body = {
code: 200,
msg: "password不能爲空",
result: {}
}
return
} else {
// other operat
}
ctx.body = {
code: 200,
msg: "請求成功",
result: { pageSize, pageNo, user, password }
}
拋出錯誤
ctx.status = 500
或者 ctx.throw(5000);
或者 throw new Error(500, '信息有誤,請重填')
中間件的使用
必須使用next()連接不然不執行下一個中間件即app.use(()=>{})裏面的內容 中間件的執行順序是洋蔥模型 即中間件如果有await的話先執行await的內容然後在執行再從下到上執行
app.use((ctx, next) => {
next()
})
koa爲什麼有很多的async和await?可以不用或者有別的方案嗎(可以 有)
async函數是es7的異步函數,await只能在其之內 其他地方會出錯 await是等待異步操作結束的意思
你可能會覺得你有時候用不用await好像沒有區別 有兩個可能
第一 你的代碼中並沒有異步的操作 比如數據請求(koa操作mongodb也是異步的)
第二 你的異步請求非常快
你的數據請求了api 然後後面的代碼邏輯是和數據請求的結果是有關聯的這時候你沒有使用async await等待異步請求完成就繼續其他操作是會出現問題的
你當然也可以不使用async和await,async和await只是不讓你再用回調的方式而已 你不用就得使用then()操作異步請求的結果,這看起來相比之下會很不優雅,async await會返回prosime對象
中間件驗證
// tokenValid.js
const jwt = require('jsonwebtoken')
module.exports = function(req) {
const token = req.headers['authorization'];
console.log("token的值:")
console.log(token)
return jwt.verify(token, 'xxxxxxxxxxxx', function(err, decoded) {
if (err) {
return {
success: false,
data: {
code: -101,
message: 'Failed to authenticate token.'
}
}
}
return {
success: true,
}
})
}
user.js
const tokenValid = require('./tokenValid');
const checkLogin = async(ctx, next) => {
if (['/user/login', '/user/loginout'].indexOf(ctx.url) !== -1) {
await next();
return;
}
const isLogin = await tokenValid(ctx.request); //
// console.log(ctx.request)
console.log("login vallid返回值:")
console.log(isLogin)
if (!isLogin.success) {
ctx.response.status = 401;
// ctx.response.body = 'token Vaild Error';
// ctx.throw(401, 'token Vaild Error');
ctx.body = {
code: 401,
msg: 'token Vaild Error'
}
return
}
await next();
}
router.use(checkLogin);
nuxt
nuxt中ssr服務器異步請求的時候asyncData的時候token處理
因爲服務器端沒有window對象所以不能使用緩存的方式axios帶上token 可以通過設置cookie(js-cookie) 即設置cookie的時候服務端是可以獲取到的(在asyncData(({app})=>{}) 對象裏面獲取cookie對象)
跳轉的時候用router對象 用window會報錯
數據請求
const Cookie = require("js-cookie");
async asyncData({ app, params, store, require }) {
let { data } = await post("http://127.0.0.1:3000/shop/queryShop", {}, app);
const token = {
token: "this is asyncData post token ####"
};
// store.commit("setToken", token);
Cookie.set("token", token);
return { demo: store.state.token };
}
login.vue
登陸成功後設置
Cookie.set("token", res.token, { expires: 2*(60 * 60 * 1000) });
Cookie.set("userInfo", res.result.user, { expires: 2*(60 * 60 * 1000) });
待更新.....