[ad_1]
I have three collections: users
, questions
and answers
. The answers
collection contains the question_id and user_id. In the application level I need to find all users who fits in a query and not have answered a question yet. I was doing it building the query on application level with a $nin clause containing all the users ids who already have answered the question.
already_answered = [
ObjectId(a["user_id"])
for a in db.answers.find({"question": question_id}, {"user_id": 1})
]
query = {
...
"$nin": already_answered
}
users = db.users.find(query)
But, for questions who have many answers, the query document extrapolates the 16MB limit from MongoDB.
Then, I want to delegates this part of the query for the database level with $lookup
.
users = db.users.aggregate(
[
{
"$match": query
},
{
"$lookup": {
"from": "answers",
"let": {"str_user_id": {"$toString": "$_id"}},
"pipeline": [
{
"$match": {
"$expr": {
"$and": [
{"$eq": ["$user", "$$str_user_id"]},
{
"$eq": [
"$question_id",
question_id,
]
},
]
}
},
}
],
"as": "answered",
}
},
{"$match": {"answered": {"$size": 0}}},
{"$project": {"_id": 1}},
]
)
But this is horrendous slow. How can I achieve the expected result?
[ad_2]