$graphLookup question

This question was inspired by Chapter 3’s final quiz regarding the $graphLookup, but not directly related to it. As noted in another post by @Eliott_Coyac , the question and answer are both a bit misleading.

Suppose we did want to include only destinations that could be reached by departing from one of the “OneWorld” alliance carriers based in Gernany, Spain, or Canada from their respective home base with a single layover. That is, we can depart from KTE on Air Berlin, from BRN on Iberia Airlines, or from LVI on Canadian Airlines. Then with a single layover, where can we go if we stay on one of those airlines?

In reading the given answer, I think this is what they tried to answer, but I think the pipeline given ignores the possibility that there is a second leg that can be reached by one of the carriers above, but only by using a carrier not in the list for the first leg. To address that possibility, I was looking to modify their pipeline, the first part of which looks like this, to address this:

[{$match: {
  name: "OneWorld"
}}, {$graphLookup: {
  from: 'air_airlines',
  startWith: "$airlines",
  connectFromField: "name",
  connectToField: "name",
  as: 'airlines',
  maxDepth: 0,
  restrictSearchWithMatch: {
    country: { $in: ["Germany", "Spain", "Canada"] }
  }
}}, {$graphLookup: {
  from: 'air_routes',
  startWith: "$airlines.base",
  connectFromField: 'dst_airport',
  connectToField: 'src_airport',
  as: 'connections',
  maxDepth: 1
}}, ...

In the second $graphLookup, which links in the routes by src_airport and dst_airport, I wanted to restrict the routes with a “restrictSearchWithMatch” expression like this…

{
    $graphLookup: {
        from: 'air_routes',
        startWith: "$airlines.base",
        connectFromField: 'dst_airport',
        connectToField: 'src_airport',
        as: 'connections',
        maxDepth: 1,
        restrictSearchWithMatch: {
            "airline.name": {
                $in: [ "$airlines.name" ]
            }
        }
    }
}

I was unable to get this to work. In fact, any match on “airline.name” failed to bring in any connections. For example…

{
    $graphLookup: {
        from: 'air_routes',
        startWith: "$airlines.base",
        connectFromField: 'dst_airport',
        connectToField: 'src_airport',
        as: 'connections',
        maxDepth: 1,
        restrictSearchWithMatch: {
            "airline.name": "Air Berlin"
            }
        }
    }
}

I also tested the “restrictSearchWithMatch” on the “src_airport” field like this:

}}, {$graphLookup: {
  from: 'air_routes',
  startWith: "$airlines.base",
  connectFromField: 'dst_airport',
  connectToField: 'src_airport',
  as: 'connections',
  maxDepth: 1,
  restrictSearchWithMatch: {
    src_airport: "LVI"
  }
}}

And while this gives 6 connections, none of them are on “Canadian Airlines”, which makes no sense to me.

Can anyone tell me what I am missing?

Update:

Most of the issues were due to data. The base field in the air_airlines collection doesn’t seem to correspond to the src_airport of the air_routes collection. For example, in air_airlines, the base for “Iberia Airlines” is “BRN”, which is the Bern airport in Switzerland. The actual base for “Iberia Airlines” is Madrid Barajas in Spain (MAD).

However, it should be noted that even with “correct” data, the $graphLookup that attempted to restrictSearchWithMatch on "$airlines.name" would fail. The reason is that, according to the documentation, you cannot use “aggregation expressions” in the context of a restrictSearchWithMatch, so "$airline.name" would be treated as a literal string and not an array of values from the source document.

Hi @Eric_Stimpson,

I am glad that you were able to debug the issue :clap:

Note that the MongoDB Aggregation course will be updated and this will remove all such complexities in the data as well as lab statements.

Please feel free to reach out if you have any additional questions.

Kind Regards,
Sonali Mamgain

1 Like