I need to join 2 collections using $lookup, but filtering some documents before joining:
collection a
doc_1 => { "join_field": 33}
doc_2 => { "join_field": 78}
...
doc_100000000 => { "join_field": 33}
collection b
doc_1 => { "filter_field": "X", "join_field": [ 33, 65, 89], }
doc_2 => { "filter_field": "X", "join_field": [ 55, 5423, 998] }
doc_3 => { "filter_field": "Y", "join_field": [ 33, 86] }
...
doc_100000000 => { "filter_field": "X", "join_field": [ 33, 95] }
I need to start the aggregation from collection “a”, so starting with “b” is not an option.
b.join_Field array is an indexed field.
If I make a normal $lookup between “a” and “b” (without filter) it uses the index correctly, and it returns all the matches from “b” in the response
db.a.aggregate([
{ $match: { "join_field": 33 } },
{ $lookup: {
from: "b"
localField: "join_field", // REGULAR FIELD
foreignField: "join_field" // ARRAY
as: "lookup"
}}
])
// response
{
"join_field": 33,
"lookup": [
{ "filter_field": "X", "join_field": [ 33, 65, 89], },
{ "filter_field": "Y", "join_field": [ 33, 86] },
...
{ "filter_field": "X", "join_field": [ 33, 95] }
]
}
I have changed the query to this version, expecting to get the same. However, the $in expression written like this returns an error, which suggest to think that indexes are not being used.
db.a.aggregate([
{ $match: { "join_field": 33 } },
{ $lookup: {
from: "b"
let: { "jf": "$join_field" },
pipeline: [
{ $match: {
$expr: { $in: [ "$$jf", "$join_field" ] }
}}
]
as: "lookup"
}}
])
// ERROR: $in requires an array as a second argument, found: missing",
I need to filter collection “b” on this $lookup stage on the pipeline, but based on showed, I cannot do it if indexes are not allowed on this version of the query.
Is there a way to do it?
Thank you very much