Slice an array based on matching conditions with $lookup

Viewed 545

I'm discovering Mongodb and its queries with pipelines and I'm struggling on a case.

I'm looking for each pathsList document where I can find a path from a position B to a position C

  • Inputs: 10 and 12
  • Output: [pathsList] (I expect only 1 result in this example, but more likely an array later on)

Let's say I have the 2 following pathsList documents from pathsListsCollection, they have an array of path documents

-------------
pathsList = {
    _id: ObjectId(...),
    pathIds: [path1Id, path2Id, path3Id]
}
-------------
path1 = {
    _id: ObjectId(...),
    positionStart: 8,
    positionFinal: 10,
    index:0
}
-------------
path2 = {
    _id: ObjectId(...),
    positionStart: 10,
    positionFinal: 12,
    index:1
}
-------------
path3 = {
    _id: ObjectId(...),
    positionStart: 12,
    positionFinal: 14,
    index:2
}
-------------

-------------
pathsList = {
    _id: ObjectId(...),
    pathIds: [path4Id, path5Id, path6Id]
}
-------------
path4 = {
    _id: ObjectId(...),
    positionStart: 14,
    positionFinal: 12,
    index:0
}
-------------
path5 = {
    _id: ObjectId(...),
    positionStart: 12,
    positionFinal: 10,
    index:1
}
-------------
path6 = {
    _id: ObjectId(...),
    positionStart: 10,
    positionFinal: 8,
    index:2
}
-------------

So far I've done something like this:

pathsListCollection.aggregate([
    {
    $lookup:{
        from: "pathsCollection",
        localField: "pathIds",
        foreignField: "_id",
        as: paths
        }
    },
    {
        $match:{
            paths.positionStart : 10 // first input value
        }
    },
    {
        $match:{
            paths.positionFinal : 12  // second input value
        }
    },
])

Doing this I get the 2 pathsList docs.

Now, how can I change this aggregate to find only the one having a positionStart = 10 and positionFinal = 12 in that specific order How can try to validate the second expression only if the first one already has been validate?

I've looked into $slice trying to slice the paths array after the first $match, and continue the query with the rest of it, but couldn't find any revelent syntax to do it.

ie: working with the first pathsList, I reach the first $match with a paths array like that :

[{
    _id: ObjectId(...),
    positionStart: 8,
    positionFinal: 10,
    index:0
},
{
    _id: ObjectId(...),
    positionStart: 10,     // first $match here
    positionFinal: 12,
    index:1
},
{
    _id: ObjectId(...),
    positionStart: 12,
    positionFinal: 14,
    index:2
}]

and I want to do the next $match on an array like that :

[{
    _id: ObjectId(...),
    positionStart: 10,
    positionFinal: 12,    // second $match has to start from this elem of the array
    index:1
},
{
    _id: ObjectId(...),
    positionStart: 12,
    positionFinal: 14,
    index:2
}]

Is it possible to do that? would it be easier to query pathsCollection rather than pathsListsCollection in first place?

However, I'm open to any different approach or thoughs which could help me to solve that problem Thanks in advance

1 Answers
Related