Here is the scenario:
- There are two collections
- The first collection has a one to many relationship to the second collection. The second collection has a one to one with the first collection.
- The query is performed on 3 fields all of which are index
- 2 of those indexes are on the first collection and 1 is on the second collection
- The results need to support pagination
Currently the best I could come up with is using an aggregation. The stages look something like this:
Aggregation -> match on 2 indexed values on the first collection -> sort -> lookup with a pipeline that has a match on the relationship property in both collections AND match based on the potential search value on an indexed value in the second collection -> match with OR that looks at 2 search fields in the first collection using regex or if the project from the lookup contained any results -> limit -> project with values
The concerns are that the search will do a join on all of the documents in the first collection with the second collection during the lookup. Keep in mind everything being searched is index, but the lookup is the major concern here. Suggestions to do this the right way? Better way?
Code example:
db.collection1.aggregate( [
{
$match: { // initial filters based on indexed values
field1: "somevalue",
field2: "somevalue"
},
},
{
$sort: {
firstSortField: -1, _id: -1 // sort results by needed order
}
},
{
$lookup: // join with another collection to search on a specific value
{
from: collection2,
localField: someLocalField,
foreignField: someForeignField,
as: "someJoinedFields"
}
},
{
$addFields: {
extraField: ["$someJoinedFields.someExtaField"] // add potential array of values
}
},
{
$match: (
{
$or: [
{ field3: {$regex: ""}}, // potential search field
{ field4: {$regex: ""}}, // potential search field
{ extraField: {$regex: ""}} // potential search field
]
}
)
},
{
$limit: 100 // limit to 100 results for pagination
},
{
$project: { // final results
finalField: 1,
finalField2: 1,
finalField3: 1
}
}
])