
[英]Most efficient way to always return truthy using the least characters on an expression?
[英]Most efficient way to return values conditionally from populated Models using Mongoose and GraphQL?
我的目标是根据填充后从模型本身检索到的数据有条件地返回 Model 值。
这是我目前的解决方案:
const bcrypt = require("bcryptjs")
const jwt = require("jsonwebtoken")
const moment = require("moment")
const User = require("../../models/user")
const Post = require("../../models/post")
const { checkAuthorSettings, checkFollowingAuthorSettings } = require('../../shared/utility')
login: async ({ email, password }) => {
try {
const user = await User.findOne({ email }).populate([
{
path: 'posts',
model: 'Post',
populate: [
{
path: 'author',
model: 'User',
},
{
path: 'comments',
model: 'Comment',
populate: {
path: 'author',
model: 'User',
},
},
],
},
{
path: 'following',
model: 'User',
populate: {
path: 'posts',
model: 'Post',
populate: [
{
path: 'author',
model: 'User',
},
{
path: 'comments',
model: 'Comment',
populate: {
path: 'author',
model: 'User',
},
},
],
},
},
{
path: 'favourites',
model: 'Post',
populate: [
{
path: 'author',
model: 'User',
},
{
path: 'comments',
model: 'Comment',
populate: {
path: 'author',
model: 'User',
},
},
],
},
])
if (!user) throw new Error("An Account by that Email was not found!")
if (!password) throw new Error("Please enter your password")
const passIsValid = bcrypt.compareSync( password, user.password )
if (!passIsValid) throw new Error("Incorrect Password")
const token = jwt.sign(
{
_id: user._id,
email: user.email,
},
`${process.env.JWT_SECRET}`,
{ expiresIn: "1h" }
)
user.status = "online"
user.logged_in_at = moment().format()
await user.save()
return {
...user._doc,
token,
token_expiry: 1,
email: user.settings.display_email ? user.email : "",
website: user.settings.display_website ? user.website : "",
password: null,
posts: await checkAuthorSettings(user.posts),
following: await checkFollowingAuthorSettings(user.following),
favourites: await checkAuthorSettings(user.favourites),
info: JSON.stringify(user._doc.info),
geolocation: JSON.stringify(user._doc.geolocation),
settings: JSON.stringify(user._doc.settings),
}
} catch (err) {
throw err
}
},
实用程序.js:
const checkAuthorSettings = array => {
return array.map(post => {
return {
...post._doc,
author: {
...post._doc.author._doc,
email: post._doc.author._doc.settings.display_email ? post._doc.author._doc.email : "",
website: post._doc.author._doc.settings.display_website ? post._doc.author._doc.website : "",
}
}
})
}
const checkFollowingAuthorSettings = array => {
return array.map(followed => {
return {
...followed._doc,
posts: checkAuthorSettings(followed.posts)
}
})
}
exports.checkAuthorSettings = checkAuthorSettings
exports.checkFollowingAuthorSettings = checkFollowingAuthorSettings
我目前正在遍历 User 中的每个数组,我认为这远不是实现这一目标的最有效方法。
有人有比这更好的解决方案吗?
可以使用virtuals
,virtuals 的实现方式有很多种,如果要直接替换email
字段,可以使用getters
例如
const AuthorSchema = new Schema({
// other fields
email: String,
}, {
toObject: { getters: true }
})
AuthorSchema.path('email').get(function(email) {
return this.get('settings.display_email') ? email : ''
})
然后,当您在文档上调用.toObject()
时,您将获得一个virtual
值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.