Я реализую "подобную" функциональность, работая с nodejs и mongodb.
По сути, у пользователя модели есть массив свойств, в котором я храню все идентификаторы понравившегося документа.
Затем я смотрю в этом массиве, если в нем находится понравившийся документ, я оставляю один на лайки и убираю идентификатор из массива, а если он не включается, я добавляю один лайк и pu sh это в массив.
По сути, я придумал 2 решения:
Здесь я использую javascript, чтобы связать лог c массива идентификаторов.
User.findOne(query)
.then(user => {
let add = 0;
let likedShirts = user.likedShirts
if (!likedShirts.includes(shirtId)) {
add = 1
likedShirts.push(shirtId)
} else {
add = -1
let index = likedShirts.indexOf(shirtId)
likedShirts.splice(index, 1)
}
Shirt.findByIdAndUpdate(shirtId, { $inc: { likes: add } }, { new: true, runValidators: true }, (err, result) => {
if (err) {
res
.status(500)
.json({ message: err.message })
return;
}
user.likedShirts = likedShirts
user.save()
res
.status(200)
.json({ likes: result.likes, shirtId: shirtId })
})
})
.catch(err => {
res
.status(500)
.json({ message: err.message })
return;
})
И здесь я использую чистый мон go, но сначала я нахожу одного пользователя, затем рубашку, а затем снова пользователя. Я как-то нахожу это уродливым, но я всегда стараюсь использовать как можно меньше javascript.
User.findOne(query)
.then(user => {
if (!user.likedShirts.includes(shirtId)) {
Shirt.findByIdAndUpdate(shirtId, { $inc: { likes: 1 } }, { new: true, runValidators: true }, (err, result) => {
User.findOneAndUpdate(query, { $push: { likedShirts: shirtId } }).then(() => {
if (err) {
res
.status(500)
.json({ message: err.message })
}
res
.status(200)
.json({ likes: result.likes, shirtId: shirtId })
})
.catch(err => {
res
.status(500)
.json({ message: err.message })
})
})
} else {
Shirt.findByIdAndUpdate(shirtId, { $inc: { likes: -1 } }, { new: true, runValidators: true }, (err, result) => {
User.findOneAndUpdate(query, { $pull: { likedShirts: shirtId } }).then(() => {
if (err) {
res
.status(500)
.json({ message: err.message })
}
res
.status(200)
.json({ likes: result.likes, shirtId: shirtId })
})
.catch(err => {
res
.status(500)
.json({ message: err.message })
})
})
}
})
.catch(err => {
res
.status(500)
.json({ message: err.message })
})
То, что я хотел знать, это в основном, и вообще, какой вариант лучше? Это нормально, если я сделаю больше консультаций с базой данных (как во втором примере), или лучше использовать javascript. Я пытался измерить время, оно в основном то же самое, но я использую мало пользователей и данных. Есть правило? Лучшая практика?