#mongodb #mongoose #mongodb-query #aggregation-framework #aggregate
#mongodb #mongoose #mongodb-запрос #агрегация-фреймворк #агрегированный
Вопрос:
Я работаю над приложением, в котором есть функция обмена сообщениями (чат), и я хочу получить всех пользователей, которые у меня есть или которые отправили мне сообщения, и сгруппировать всех этих пользователей в том порядке, в котором контакт с самым последним сообщением попадает в начало. и подсчитал все сообщения, которые я получил от другого пользователя, которые я еще не прочитал.
Модель сообщений Mongo
const userChat = new Schema({
senderUserId: {
type: Schema.Types.ObjectId,
ref: "User"
},
message: {
type: String
},
room: {
type: Array
},
files: {
type: Array
},
read: {
type: Boolean,
default: false
},
receiverUserId: {
type: Schema.Types.ObjectId,
ref: "User"
}
}, {
timestamps: true
})
Мой агрегат MongoDB
const user = await UserChat.aggregate([{
$match: {
$and: [{
$or: [{
receiverUserId: req.user._id
}, // User is in recepients
{
senderUserId: req.user._id
}, // or the sender
],
}, ],
},
},
{
$sort: {
createdAt: -1,
},
},
{
// if the message is send by me then i group the "$receiverUserId"
// if not that mean i am the receiver so i group the "$senderUserId"
$group: {
_id: {
$cond: {
if: {
$eq: ["$senderUserId", req.user._id]
},
then: "$receiverUserId",
else: "$senderUserId"
}
},
count: {
$sum: {
$cond: ["$read", 0, 1]
},
},
createdAt: {
$first: "$createdAt",
},
},
},
$lookup: {
from: "users",
localField: "_id",
foreignField: "_id",
as: "user",
},
}, {
$sort: {
createdAt: -1,
},
}, {
$project: {
_id: 1,
count: 1,
createdAt: 1,
user: 1,
},
}, ]);
пример данных, которые я хочу получить
скажем, например, у нас есть два пользователя, которые пишут друг другу. пользователя 1 зовут Папи Джонсон, а другого — принц Мишель.
Принц Мишель отправляет два сообщения Папи Джонсону. поскольку Папи Джонсон еще не прочитал сообщение принца Мишеля, поэтому, когда Папи Джонсон запрашивает отправленные или полученные им сообщения, результат должен быть:
{
_id: 5f8cf7e3c68dd730b5edb8a9, // the ID of Prince Michel
count: 2, // number of message unread send by Prince Michel to Papi johnson
createdAt: 2020-10-19T02:27:39.759Z, // the last message receive
user: [ [Object] ] // in then the user info of Prince Michel
}
и когда принц Мишель запрашивает сообщение, которое он отправил или получил, результат должен быть:
{
_id: 5f8cf8f5b76f3e3d5e6e249f,// the ID of Papi johnson
count: 0, // number of message unread send by Papi johnson to Prince Michel
createdAt: 2020-10-19T02:27:39.759Z,
user: [ [Object] ]// in then the user info of Papi johnson
}
это то, что я получаю в результате:
пример на фото
получен ответ на примере Papi и Prince
** проблема в том, что я получаю одинаковое количество непрочитанных сообщений для обоих пользователей. Я думаю, что проблема может заключаться в том, что запрос «$ group» и «$ sum» учитывает не только непрочитанное сообщение, полученное пользователем, но и все непрочитанные сообщения, отправленные или полученные пользователем. прошло более 10 дней с тех пор, как я вел блог на этом уровне, и я не знаю, что на самом деле делать. **
когда Папи Джонсон запрашивает отправленные или полученные им сообщения, результатом является :
{
_id: 5f8cf7e3c68dd730b5edb8a9, // the ID of Prince Michel
count: 2,
// I think here the "$ group" and "$ sum"
//query does not count only unread message received by the user,
// but rather all unread message that is sent or received by the user.
createdAt: 2020-10-19T02:27:39.759Z, // the last message receive
user: [ [Object] ] // in then the user info of Prince Michel
}
и когда принц Мишель запрашивает отправленное или полученное им сообщение, результатом является :
{
_id: 5f8cf8f5b76f3e3d5e6e249f,// the ID of Papi johnson
count: 2,
// I think here the "$ group" and "$ sum"
//query does not count only unread message received by the user,
// but rather all unread message that is sent or received by the user.
createdAt: 2020-10-19T02:27:39.759Z,
user: [ [Object] ]// in then the user info of Papi johnson
}
Комментарии:
1. Можете ли вы опубликовать, какой результат вы получаете сейчас и чего ожидаете?
2. привет @wak786 я делаю некоторые обновления, надеюсь, это ответит на ваш вопрос. Спасибо
3. да, теперь я не понял вопроса.
4. можете ли вы предоставить несколько примеров документов, чтобы я мог использовать их для запроса wirte. Вы можете создать
Mongo Playground
и поделиться ссылкой со мной. mongoplayground.net5. @wak786 вот ссылка mongoplayground.net/p/jrrlObv—b4