I’d like filter all records with populated attributes in a query. This is TypeScript code:
router.get("/slice", async (req, res) => {
if (req.query.first && req.query.rowcount) {
const first: number = parseInt(req.query.first as string);
const rowcount: number = parseInt(req.query.rowcount as string);
const question: string = req.query.question as string;
if (question) {
let result = await QuestionAnswer.QuestionAnswer.find().populate('question_id').exec();
let filtered: any[] = [];
result.forEach((record) => {
let q = record.get("question_id.question");
if (q.includes(question))
filtered.push(record);
});
filtered = filtered.slice(first, first + rowcount);
res.send(filtered);
} else {
let result = await QuestionAnswer.QuestionAnswer.find().skip(first).limit(rowcount).populate('question_id');
res.send(result);
}
} else {
res.status(404).send();
}
});
Schema is the following:
const questionSchema = new Schema({
question: {
type: String,
required: true,
},
topic_id: {
type: Types.ObjectId,
required: true,
ref: 'topic',
},
explanation: {
type: String,
required: true,
},
});
const questionAnswerSchema = new Schema({
question_id: {
type: Types.ObjectId,
required: true,
ref: 'question',
},
answer: {
type: String,
required: true,
},
isCorrect: {
type: Boolean,
required: true,
},
});
How can I do it in a query instead array filtering?
I found a solution with aggregation and lookup. Is there any way with find?
2
Answers
With aggregation I can filter the result with the following code:
Something like this may work using regex:
Specifying "i" in options is for case insensitive filtering.
Haven’t tested it, but should work as expected.