Я пытаюсь запросить свою коллекцию матчей (игр) и выяснить, отправлял ли определенный пользователь данные в массив объектов reportMessages.
const results = await Match.findOne({ 'users': req.params.userIdOfReportSender, '_id': req.params.matchId, 'reportMessages.sentBy': req.params.userIdOfReportSender }, 'reportMessages' )
Однако приведенный выше запрос возвращает следующее:
{
_id: 5fd382c65d5395e0778f2f8a,
reportMessages: [
{
_id: 5fd610f27ae587189c45b6ca,
content: 'jajatest',
timeStamp: 2020-12-13T13:02:42.102Z,
sentBy: 'XbVvm6g3nsRmPg3P1pBvVl84h6C2'
},
{ sentBy: "'anotheruser123" }
]
}
Как я могу заставить его возвращать только первое сообщение reportMessage, то есть сообщение, отправленное XbVvm6g3nsRmPg3P1pBvVl84h6C2?
Документы Mongoose findOne (https://mongoosejs.com/docs/api.html#model_Model.findOne) показывают, что вы можете предоставить аргументы, чтобы указать, какие поля выбрать (в их случае «длина имени», но не показывать способ выбирать поля только в том случае, если они соответствуют определенному условию.
Это вообще возможно? Пытался гуглить этот, казалось бы, простой вопрос в течение довольно долгого времени, но безуспешно.
С уважением
Вы можете получить только тот вложенный документ, который вам нужен, с помощью этого запроса агрегации:
Match.aggregate([
{
$match: { _id: req.params.matchId }
},
{
$project: {
reportMessages: {
$filter: {
input: '$reportMessages',
as: 'msg',
cond: { $eq: ['$$msg.sentBy', req.params.userIdOfReportSender] }
}
}
}
},
{
$project: {
reportMessage: { $arrayElemAt: [ '$reportMessages', 0 ] },
}
},
{ $replaceWith: '$reportMessage' }
]);
Обратите внимание, что вам нужно указать только документ _id
, чтобы получить один результат, поскольку _id
s уникальны.
Спасибо. После обертывания ObjectId вокруг req.params.matchId в условии $match это сработало. Все еще не уверен, почему это нужно делать для этого запроса агрегации, но, например. в операции updateOne мне не нужно оборачивать ObjectId вокруг него, и я могу продолжать использовать значение req.params.matchId (которое, как мне кажется, является строкой).