Объем проекта : я делаю новостную ленту, как Facebook. И у меня есть функция кнопки «Мне нравится», которая при нажатии добавляет сообщение в элемент публикации.
Проблема Допустим, у меня есть два поста, пост А и пост Б.
Если мне нравится пост A, и мне нравится снова, тогда мой сервер возвращает сообщение «Пост уже понравился пользователю», хорошо, это работает.
Однако, если мне нравится пост B, то сервер возвращает то же самое сообщение «Пост уже понравился пользователю»
Запрос:
Feed.findOne({
owner: req.body.authorId,
$and: [
{
"posts.likes.likeList": {
$elemMatch: { user: req.user._id }
}
},
{ posts: { $elemMatch: { _id: req.body.postId } } }
]
}).then(checkedFeed => {
if (checkedFeed) {
return res.status(400).json({ Error: "User has already liked post" });
}
Что я думаю, проблема в Когда пользователю нравится пост B, а пост A нравится, оператор $and
сопоставляет req.user._id
с posts.likes.likeList
поста A в первом индексе массив $and
. Затем он соответствует _id
из posts
во втором индексе массива $and
. А затем возвращает весь канал как совпадение.
Итак, если я прав в этом отношении, как мне написать запрос, который сопоставляет идентификатор записи (второй индекс массива $and
) со списком пользователей post.likes.likeList
?
Схема
{
owner: {
type: Schema.Types.ObjectId,
ref: "userType"
},
posts: [
{
likes: {
totalLikes: { type: Number, default: 0 },
likeList: [
{
user: { type: Schema.Types.ObjectId, ref: "User" },
avatar: { type: String },
name: { type: String },
date: {
type: Date,
default: Date.now
}
}
]
}
});
Данные испытаний *
{
//POST B <-------
"_id" : ObjectId("5d0a61bc5b835b2428289c1b"),
"owner" : ObjectId("5c9bf6eb1da18b038ca660b8"),
"posts" : [
{
"likes" : {
"totalLikes" : 0,
"likeList" : []
},
"_id" : ObjectId("5d0a61bc5b835b2428289c1c"),
"postBody" : "Test text only",
"author" : {
"userType" : "User",
"user" : ObjectId("5c9bf6eb1da18b038ca660b8"),
"name" : "Amari DeFrance",
"avatar" : "https://stemuli.blob.core.windows.net/stemuli/profile-picture-e1367a7a-41c2-4ab4-9cb5-621d2008260f.jpg"
}
},
{
//Post A <------
"likes" : {
"totalLikes" : 1,
"likeList" : [
{
"_id" : ObjectId("5d0a66efbac13b4ff8b3b1c8"),
"user" : ObjectId("5c9bf6eb1da18b038ca660b8"),
"avatar" : "https://stemuli.blob.core.windows.net/stemuli/profile-picture-e1367a7a-41c2-4ab4-9cb5-621d2008260f.jpg",
"name" : "Amari DeFrance",
"date" : ISODate("2019-06-19T16:46:39.177Z")
}
]
},
"postBody" : "Test photo",
"author" : {
"userType" : "User",
"user" : ObjectId("5c9bf6eb1da18b038ca660b8"),
"name" : "Amari DeFrance",
"avatar" : "https://stemuli.blob.core.windows.net/stemuli/profile-picture-e1367a7a-41c2-4ab4-9cb5-621d2008260f.jpg"
},
"date" : ISODate("2019-06-19T16:25:26.123Z")
}
],
"__v" : 3
}
Новый запрос за предложенный ответ
Feed.aggregate([
{
$match: {
$expr: {
$and: [
{
$eq: ["$owner", req.body.authorId]
},
{
$anyElementTrue: {
$map: {
input: "$posts",
in: {
$and: [
{
$eq: ["$$this._id", req.body.postId]
},
{
$anyElementTrue: {
$map: {
input: "$$this.likes.likeList",
as: "like",
in: {
$eq: ["$$like.user", req.user._id]
}
}
}
}
]
}
}
}
}
]
}
}
}
]).then(checkedFeed => {
if (checkedFeed.length !== 0) {
return res.status(400).json({ Error: "User has already liked post" });
}
тестовый запрос MongoDB с постом B, которому понравился пост пользователя