mongoose addfiled, aggregate или function
Mongoose Models:
const replySchema = new mongoose.Schema({
text: {type:String, required: true, minlength: 1},
delete_password: {type:String, required: true, minlength: 1, select: false},
reported: {type:Boolean, default: false},
created_on: {type: Date, default: Date}
});
const replyModel = mongoose.model('MessageBoardReply', replySchema);
const threadSchema = new mongoose.Schema({
text: {type:String, required: true, minlength: 1},
replies: {type:[replySchema], default:[]},
delete_password: {type:String, required: true, minlength: 1, select: false},
reported: {type:Boolean, default: false},
created_on: {type: Date, default: Date},
bumped_on: {type: Date, default: Date},
// replycount: ? replies.length auto
});
const threadModel = mongoose.model('MessageBoardThread', threadSchema);
const boardSchema = new mongoose.Schema({
board: {type:String, required: true, minlength: 1},
threads: {type:[threadSchema], default:[]}
});
const msgBoard = mongoose.model('MessageBoard', boardSchema);
Запрос:
msgBoard.findOne(
{board:board},
(err,data)=>{
if(err || !data)
return res.json(err);
return res.json(data.threads)
}
);
Ответ:
[
{
"_id":"626445037832c9629eba1f23",
"text":"Text Thread",
"created_on":"2022-04-23T18:27:14.927Z",
"bumped_on":"2022-04-23T18:27:14.927Z",
"replies":[],
"replycount":0 // ? replies.length
}
]
Вопросы:
- Можно ли, в схему добавить автоматический счётчик, без ручных махинаций при обновлениях.
- Можно ли, в схему добавить функцию, при запросе которая будет это делать.
- Через aggregate, как добавить каждому объекту из threads, поле "replycount": replies.length (то есть "board.threads[i].replycount" : board.threads[i].replies.length)
Ответы (1 шт):
Автор решения: Владимир Комяк
→ Ссылка
Один из вариантов обработки ответа:
let threads = (await msgBoard.aggregate([
{$match: {board:board}},
{$unset: ['threads.delete_password']},
{$addFields: {'threads.replycount': -1}}
]))[0].threads;
threads = threads.map(th=>{
th.replycount = th.replies.length;
return th;
});
Очень похожее решение, но с ошибкой:
let threads = (await msgBoard.aggregate([
{$match: {board:board}},
{$unset: ['threads.delete_password']},
{$addFields: {'threads.replycount':{
$map:{
input:'$threads',
as:'th',
in:{ $size:'$$th.replies'}
}
}}}
]))[0].threads;
// ответ будет весь массив, а не нужный элемент