summaryrefslogtreecommitdiff
path: root/jstests/aggregation/sources/graphLookup/airports.js
blob: 801e15c3bbbda31f74c3b88e51097f803762fd50 (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
90
91
92
93
// Cannot implicitly shard accessed collections because unsupported use of sharded collection
// for target collection of $lookup and $graphLookup.
// @tags: [assumes_unsharded_collection]

// 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.commandWorked(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);
}());