summaryrefslogtreecommitdiff
path: root/jstests/aggregation/sources/graphLookup/airports.js
blob: 71a38e268b890af201efa34f18e4b3dc71b0501b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// In MongoDB 3.4, $graphLookup was introduced. In this file, we test some complex graphs.

(function() {
    "use strict";

    var local = db.local;
    var foreign = db.foreign;

    local.drop();
    foreign.drop();

    var airports = [
        {_id: "JFK", connects: ["PWM", "BOS", "LGA", "SFO"]},
        {_id: "PWM", connects: ["BOS", "JFK"]},
        {_id: "BOS", connects: ["PWM", "JFK", "LGA"]},
        {_id: "SFO", connects: ["JFK", "MIA"]},
        {_id: "LGA", connects: ["BOS", "JFK", "ORD"]},
        {_id: "ORD", connects: ["LGA"]},
        {_id: "ATL", connects: ["MIA"]},
        {_id: "MIA", connects: ["ATL", "SFO"]}
    ];

    var bulk = foreign.initializeUnorderedBulkOp();
    airports.forEach(function(a) {
        bulk.insert(a);
    });
    assert.writeOK(bulk.execute());

    // Insert a dummy document so that something will flow through the pipeline.
    local.insert({});

    // Perform a simple $graphLookup and ensure it retrieves every result.
    var res = local
                  .aggregate({
                      $graphLookup: {
                          from: "foreign",
                          startWith: "PWM",
                          connectFromField: "connects",
                          connectToField: "_id",
                          as: "connections"
                      }
                  })
                  .toArray()[0];

    // "foreign" represents a connected graph.
    assert.eq(res.connections.length, airports.length);

    // Perform a $graphLookup and ensure it correctly computes the shortest path to a node when more
    // than one path exists.
    res = local
              .aggregate({
                  $graphLookup: {
                      from: "foreign",
                      startWith: "BOS",
                      connectFromField: "connects",
                      connectToField: "_id",
                      depthField: "hops",
                      as: "connections"
                  }
              },
                         {$unwind: "$connections"},
                         {$project: {_id: "$connections._id", hops: "$connections.hops"}})
              .toArray();

    var expectedDistances = {BOS: 0, PWM: 1, JFK: 1, LGA: 1, ORD: 2, SFO: 2, MIA: 3, ATL: 4};

    assert.eq(res.length, airports.length);
    res.forEach(function(c) {
        assert.eq(c.hops, expectedDistances[c._id]);
    });

    // Disconnect the graph, and ensure we don't find the other side.
    foreign.remove({_id: "JFK"});

    res = db.local
              .aggregate({
                  $graphLookup: {
                      from: "foreign",
                      startWith: "ATL",
                      connectFromField: "connects",
                      connectToField: "_id",
                      as: "connections"
                  }
              })
              .toArray()[0];

    // ATL should now connect to itself, MIA, and SFO.
    assert.eq(res.connections.length, 3);
}());