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