Я пытаюсь реализовать механизм upvote / downvote для комментариев (аналогично механизму upvote / downvoting, найденному в reddit). У меня есть отдельная коллекция с именем commentReputation
, и документы внутри могут выглядеть так:
{
"_id" : ObjectId("5e5acb6d6034a879655c8819"),
"commentId" : ObjectId("5e5983102328a83d1a4b541f"),
"creationDate" : ISODate("2020-02-29T20:37:01.509Z"),
"upvotes" : [
ObjectId("5e5983102328a83d1a4b53e7"),
ObjectId("5e5983102328a83d1a4b53e4")
],
"downvotes" : [
ObjectId("5e5983102328a83d1a4b53e5")
]
}
Короче говоря: каждый комментарий в конечном итоге будет иметь свой собственный документ CommentReputation
(документ CommentReputation
должен быть создан как только кто-то одобряет / понижает комментарий)
Есть 2 сценария ios:
Коллекция пуста, что означает, что мне нужно создать самый первый CommentReputation
документ с заданным комментарием ID x
. В какой-то другой части проекта я использовал $setOnInsert
с { upsert: true }
, но кажется (глядя на документацию), что конвейер агрегации не поддерживает $setOnInsert
на данный момент. Есть ли другой способ решения этой проблемы?
Документ находится там, и должно произойти фактическое голосование.
a) Оба массива upvotes
и downvotes
не содержат userId
, который пытается поднять голос, поэтому он добавляется в массив upvotes
без каких-либо дальнейших действий
b) Массив upvotes
содержит userId
, который пытается поднять голос комментарий в результате userId
должен быть УДАЛЕН из массива upvotes
. (пользователь уже проголосовал за этот комментарий и во второй раз нажал кнопку upvote, которая отменяет это голосование)
c) Массив downvotes
содержит userId
. В этом случае userId
следует удалить из downvotes
и добавить к upvotes
Я пытаюсь выполнить sh вышеуказанную логику c с помощью * Метод 1045 * и конвейер агрегации, однако я не уверен, возможно ли это вообще.
То, что у меня сейчас есть, возвращает "Unrecognized pipeline stage name: '$cond'"
const updateUpvotes = {
$cond: {
if: { $elemMatch: { upvotes: ObjectID(userId) } },
then: { $pull: { upvotes: ObjectID(userId) } },
else: { $addToSet: { upvotes: ObjectID(userId) } }
}
};
db.collection(collectionName).updateOne({
commentId: ObjectID('5e5983102328a83d1a4b541f')
}, [updateUpvotes])
Я переосмыслил всю функцию? Я предполагаю, что проблему 1.
можно решить, просто создав документ CommentReputation
(при пустых upvotes
и downvotes
в то же время создается документ Comment
.
Есть ли лучший способ сделать это? Мне бы хотелось, чтобы он работал внутри одного запроса. Может быть, кто-то из вас, ребята, реализовал подобную функцию и может дать мне несколько советов по этому вопросу.