實現代碼github
最近在作一個項目涉及到mongoose的關聯查詢等等,以前作的mysql,postgresql比較多,而mongoose用的都是比較簡單的存儲數據,簡單查詢等等。
剛開始涉及ref仍是有點小暈的,查詢了相關資源,也能夠模模糊糊作出來,可是會有各類報錯。痛下決心研究透徹點,晚上熬夜到2點終於有點小眉目了。node
- node v8.5.0
- mongodb
- 結合一個接口理解
- 結合promise-async-await
- 通常採用mvc模式,本文就直接在express裏直接寫了
1. 首先創建了一個mongoose-ref項目
直接使用了express -e mongoose-ref2.在routes/index裏鏈接mongodb數據庫
const mongoose = require('mongoose'); mongoose.connect('mongodb://localhost:27017/ref');複製代碼
3.創建4個模型,用戶:User,城市:City,省份:State,國家:Country
同時創建關聯user->city->state->countryconst Schema = mongoose.Schema; const ObjectId = Schema.Types.ObjectId; const UserSchema = new Schema({ username: { type: String }, userpwd: { type: String }, userage: { type: Number }, city: { type: Schema.Types.ObjectId, ref: 'City' }, }); const CitySchema = new Schema({ name: { type: String }, state: { type: Schema.Types.ObjectId, ref: 'State' } }); const StateSchema = new Schema({ name: { type: String }, country: { type: Schema.Types.ObjectId, ref: 'Country' } }); const CountrySchema = new Schema({ name: { type: String } }); const User = mongoose.model('User', UserSchema); const City = mongoose.model('City', CitySchema); const State = mongoose.model('State', StateSchema); const Country = mongoose.model('Country', CountrySchema);複製代碼
4.主要採用promise-async-async進行邏輯處理
首先建立一個user_getCountryList函數,以下代碼
const user_getCountryList = async function (req, res) { console.log("/v1/ref start -->" + JSON.stringify(req.body)); try { const respondData = { status: res.statusCode, data: {}, error: {} }; const username = req.body.username; const userpwd = req.body.userpwd; const userage = req.body.userage; const usercityname = req.body.usercityname; const userstatename = req.body.userstatename; const usercountryname = req.body.usercountryname; const userInfoCountry = await findUserCountry({ name: usercountryname }, usercountryname);//查看國家 const userInfoState = await findUserState({ name: userstatename }, userstatename);//查看州 const userInfoCity = await findUserCity({ name: usercityname }, usercityname);//查看城市 const userInfo = await findUser({ username: username, }, username,userpwd,userage);//查看用戶信息 const updateInfoUser = await updateUser({ _id: userInfo },userInfoCity);//更新用戶信息 const updateInfoCity = await updateCity({ _id: userInfoCity }, userInfoState);//更新城市信息 const updateInfoState = await updateState({ _id: userInfoState }, userInfoCountry);//更新州信息 return res.json(respondData); } catch (error) { //錯誤處理 console.log("userCity error -->" + JSON.stringify(error)); respondData.error = error; return res.json(respondData); } }複製代碼
首先查看傳入的國家在country中有沒有,加入有,返回_id,沒有就建立傳入的國家名,並返回_id,查看findUserCountry函數對應的邏輯const findUserCountry = async function (cnd, country) { console.log("findUserCountry start --> " + JSON.stringify(cnd)); return new Promise(function (resolve, reject) { Country.findOne(cnd, function (error, data) { console.log("findUserCountry findOne data --> " + JSON.stringify(data)); if (error) { return reject(error); } if (data) { return resolve(data._id); } else { const userCountry = new Country({ name: country }); userCountry.save(function (err, data) { if (err) { console.log("userCountry.save err-->" + JSON.stringify(err)); return reject(err); } console.log("userCountry-->" + JSON.stringify(data)); return resolve(data._id); }); } }); }) }複製代碼
同理傳入的州,城市,用戶信息以一樣的方式返回_id接下來就要進行關聯user->city->state->country
通俗的說就是在User表中city保存City表中所須要的_id;也就是以前返回的_id這時就能夠用到,能夠參考updateUser函數const updateUser = async function (cnd, cityid) { console.log("updateUser start --> " + JSON.stringify(cnd)); return new Promise(function (resolve, reject) { User.update(cnd, { $set: { city: cityid } }, function (error, data) { console.log("updateUser findOne data --> " + JSON.stringify(data)); if (error) { return reject(error); } return resolve(data); }); }) }複製代碼
可使用postman模擬數據,如圖:
當傳入username 時,使用populate關聯查詢,能夠查詢出這我的的因此信息mysql
User.find({ username: user_name })
.populate('city')
.exec(function (err, docs) {
City.find({ _id: docs[0].city._id })
.populate('state')
.exec(function (err, doc) {
State.find({ _id: doc[0].state._id })
.populate('country')
.exec(function (err, result) {
const userInfo = {};
userInfo.username = docs[0].username;
userInfo.userpwd = docs[0].userpwd;
userInfo.userage = docs[0].userage;
userInfo.usercity = doc[0].name;
userInfo.userstate = result[0].name;
userInfo.usercountry = result[0].country.name;
respondData.data.push(userInfo);
return res.json(respondData);
})
})
});複製代碼
使用postman模擬接口以下git