Matching array against value in nested documents

I have searched around this problem I am facing for a bit but I haven’t found a good solution without using the $lookup parameter.

My Documents currently roughly look like this:

{
    ...
    problems:
        [ { ... id: 1, ...}, { ... id: 7, ...}, { ... id: 122, ...} ],
    solutions:
        [ { ... assignedProblems: [1, 7] ... }, { ... assignedProblems: [122] ...} ],
    ... 
}

I am now trying to match the assignedProblems array with the id in problems.

My current aggregation looks like this:

{
    $unwind: {
        path: "$solutions"
    },
    $lookup: {
        from: "problems",
        localField: "solutions.assignedProblems",
        foreignField: "id",
        as: "problems"
    }
}

This aggregation works flawlessly but is painfully slow, even when using indexes.

I have tried to replace the $lookup with following:


$match: {
        $expr: {
            $setEquals: ["$solutions.assignedProblems", "$problems.id"]
        }
     }

But this does only work if the amount of problems is the same as the elements in the assignedProblems array. This is the same case when using the $eq operator.

Is there any other way to match these id’s with the array?

Could you try the $map function? I’m away from a computer this weekend so cannot play about with it.

You say it’s slow, how many document are in the collection and average sizes of problems and solutions?

I have found a solution to what I was trying to do.

I replaced the $lookup stage to this one:

    $addFields: {
        problems: {
            $filter: {
                input: "$problems",
                cond: {
                    $in: ["$$this.id", "$solutions.assignedProblems"]
                }
            }
        }
    }

This replaces the problems array with a new one that only includes the problems objects that have an id element that is in the assignedProblems array.

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.