1
0
Fork 0

added GRAPH_NEIGHBORS

This commit is contained in:
scottashton 2014-05-20 16:45:22 +02:00
parent 3b076c4629
commit a8cacef57d
3 changed files with 124 additions and 4 deletions

View File

@ -705,6 +705,7 @@ TRI_associative_pointer_t* TRI_CreateFunctionsAql (void) {
REGISTER_FUNCTION("PATHS", "GRAPH_PATHS", false, false, "c,h|s,b", &OptimisePaths); REGISTER_FUNCTION("PATHS", "GRAPH_PATHS", false, false, "c,h|s,b", &OptimisePaths);
REGISTER_FUNCTION("GRAPH_PATHS", "GENERAL_GRAPH_PATHS", false, false, "s|s,b,n,n", &OptimisePaths); REGISTER_FUNCTION("GRAPH_PATHS", "GENERAL_GRAPH_PATHS", false, false, "s|s,b,n,n", &OptimisePaths);
REGISTER_FUNCTION("SHORTEST_PATH", "GRAPH_SHORTEST_PATH", false, false, "h,h,s,s,s|a", NULL); REGISTER_FUNCTION("SHORTEST_PATH", "GRAPH_SHORTEST_PATH", false, false, "h,h,s,s,s|a", NULL);
REGISTER_FUNCTION("GRAPH_SHORTEST_PATH", "GENERAL_GRAPH_SHORTEST_PATH", false, false, "s,s,s,s|a", NULL);
REGISTER_FUNCTION("TRAVERSAL", "GRAPH_TRAVERSAL", false, false, "h,h,s,s|a", NULL); REGISTER_FUNCTION("TRAVERSAL", "GRAPH_TRAVERSAL", false, false, "h,h,s,s|a", NULL);
REGISTER_FUNCTION("GRAPH_TRAVERSAL", "GENERAL_GRAPH_TRAVERSAL", false, false, "s,s,s|a", NULL); REGISTER_FUNCTION("GRAPH_TRAVERSAL", "GENERAL_GRAPH_TRAVERSAL", false, false, "s,s,s|a", NULL);
REGISTER_FUNCTION("TRAVERSAL_TREE", "GRAPH_TRAVERSAL_TREE", false, false, "h,h,s,s,s|a", NULL); REGISTER_FUNCTION("TRAVERSAL_TREE", "GRAPH_TRAVERSAL_TREE", false, false, "h,h,s,s,s|a", NULL);
@ -712,6 +713,7 @@ TRI_associative_pointer_t* TRI_CreateFunctionsAql (void) {
REGISTER_FUNCTION("EDGES", "GRAPH_EDGES", false, false, "h,s,s|l", NULL); REGISTER_FUNCTION("EDGES", "GRAPH_EDGES", false, false, "h,s,s|l", NULL);
REGISTER_FUNCTION("GRAPH_EDGES", "GENERAL_GRAPH_EDGES", false, false, "s,s,s|lza,ls", NULL); REGISTER_FUNCTION("GRAPH_EDGES", "GENERAL_GRAPH_EDGES", false, false, "s,s,s|lza,ls", NULL);
REGISTER_FUNCTION("NEIGHBORS", "GRAPH_NEIGHBORS", false, false, "h,h,s,s|l", NULL); REGISTER_FUNCTION("NEIGHBORS", "GRAPH_NEIGHBORS", false, false, "h,h,s,s|l", NULL);
REGISTER_FUNCTION("GRAPH_NEIGHBORS", "GENERAL_GRAPH_NEIGHBORS", false, false, "s,s,s|l", NULL);
// date functions // date functions
REGISTER_FUNCTION("DATE_NOW", "DATE_NOW", false, false, "", NULL); // NOW is non-deterministic REGISTER_FUNCTION("DATE_NOW", "DATE_NOW", false, false, "", NULL); // NOW is non-deterministic

View File

@ -4496,6 +4496,45 @@ function GRAPH_SHORTEST_PATH (vertexCollection,
params); params);
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief shortest path algorithm
////////////////////////////////////////////////////////////////////////////////
function GENERAL_GRAPH_SHORTEST_PATH (graphName,
startVertex,
endVertex,
direction,
params) {
"use strict";
if (params === undefined) {
params = { };
}
params.strategy = "dijkstra";
params.itemorder = "forward";
params.visitor = TRAVERSAL_VISITOR;
if (typeof params.distance === "string") {
var name = params.distance.toUpperCase();
params.distance = function (config, vertex1, vertex2, edge) {
return FCALL_USER(name, [ config, vertex1, vertex2, edge ]);
};
}
else {
params.distance = undefined;
}
return TRAVERSAL_FUNC("SHORTEST_PATH",
TRAVERSAL.generalGraphDatasourceFactory(graphName),
TO_ID(startVertex),
TO_ID(endVertex),
direction,
params);
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief traverse a graph /// @brief traverse a graph
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -4787,6 +4826,53 @@ function GRAPH_NEIGHBORS (vertexCollection,
return result; return result;
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief return connected neighbors
////////////////////////////////////////////////////////////////////////////////
function GENERAL_GRAPH_NEIGHBORS (graphName,
vertex,
direction,
examples) {
"use strict";
var edges = GENERAL_GRAPH_EDGES(graphName, TO_ID(vertex), direction);
var result = [ ];
FILTER(edges, examples).forEach (function (e) {
var key;
if (direction === "inbound") {
key = e._from;
}
else if (direction === "outbound") {
key = e._to;
}
else if (direction === "any") {
key = e._from;
if (key === vertex) {
key = e._to;
}
}
if (key === vertex) {
// do not return the start vertex itself
return;
}
try {
result.push({ edge: CLONE(e), vertex: DOCUMENT_HANDLE(key) });
}
catch (err) {
}
});
return result;
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- MODULE EXPORTS // --SECTION-- MODULE EXPORTS
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -4892,6 +4978,7 @@ exports.GEO_WITHIN = GEO_WITHIN;
exports.FULLTEXT = FULLTEXT; exports.FULLTEXT = FULLTEXT;
exports.GRAPH_PATHS = GRAPH_PATHS; exports.GRAPH_PATHS = GRAPH_PATHS;
exports.GRAPH_SHORTEST_PATH = GRAPH_SHORTEST_PATH; exports.GRAPH_SHORTEST_PATH = GRAPH_SHORTEST_PATH;
exports.GENERAL_GRAPH_SHORTEST_PATH = GENERAL_GRAPH_SHORTEST_PATH;
exports.GRAPH_TRAVERSAL = GRAPH_TRAVERSAL; exports.GRAPH_TRAVERSAL = GRAPH_TRAVERSAL;
exports.GRAPH_TRAVERSAL_TREE = GRAPH_TRAVERSAL_TREE; exports.GRAPH_TRAVERSAL_TREE = GRAPH_TRAVERSAL_TREE;
exports.GENERAL_GRAPH_TRAVERSAL = GENERAL_GRAPH_TRAVERSAL; exports.GENERAL_GRAPH_TRAVERSAL = GENERAL_GRAPH_TRAVERSAL;
@ -4900,6 +4987,7 @@ exports.GRAPH_EDGES = GRAPH_EDGES;
exports.GENERAL_GRAPH_EDGES = GENERAL_GRAPH_EDGES; exports.GENERAL_GRAPH_EDGES = GENERAL_GRAPH_EDGES;
exports.GENERAL_GRAPH_PATHS = GENERAL_GRAPH_PATHS; exports.GENERAL_GRAPH_PATHS = GENERAL_GRAPH_PATHS;
exports.GRAPH_NEIGHBORS = GRAPH_NEIGHBORS; exports.GRAPH_NEIGHBORS = GRAPH_NEIGHBORS;
exports.GENERAL_GRAPH_NEIGHBORS = GENERAL_GRAPH_NEIGHBORS;
exports.NOT_NULL = NOT_NULL; exports.NOT_NULL = NOT_NULL;
exports.FIRST_LIST = FIRST_LIST; exports.FIRST_LIST = FIRST_LIST;
exports.FIRST_DOCUMENT = FIRST_DOCUMENT; exports.FIRST_DOCUMENT = FIRST_DOCUMENT;

View File

@ -113,7 +113,7 @@ function ahuacatlQueryGeneralEdgesTestSuite() {
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief checks EDGES() /// @brief checks GRAPH_EDGES() and GRAPH_NEIGHBOURS()
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testEdgesAny: function () { testEdgesAny: function () {
@ -128,6 +128,9 @@ function ahuacatlQueryGeneralEdgesTestSuite() {
actual = getQueryResults("FOR e IN GRAPH_EDGES('bla3', 'UnitTestsAhuacatlVertex1/v1', 'any' , [{'what' : 'v2->v1'}]) SORT e.what RETURN e.what"); actual = getQueryResults("FOR e IN GRAPH_EDGES('bla3', 'UnitTestsAhuacatlVertex1/v1', 'any' , [{'what' : 'v2->v1'}]) SORT e.what RETURN e.what");
assertEqual(actual, [ "v2->v1" ]); assertEqual(actual, [ "v2->v1" ]);
actual = getQueryResults("FOR e IN GRAPH_NEIGHBORS('bla3', 'UnitTestsAhuacatlVertex1/v1', 'any' , [{'what' : 'v2->v1'}]) SORT e.what RETURN e");
assertEqual(actual[0].edge.what , "v2->v1");
assertEqual(actual[0].vertex._key , "v2");
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -145,6 +148,10 @@ function ahuacatlQueryGeneralEdgesTestSuite() {
actual = getQueryResults("FOR e IN GRAPH_EDGES('bla3', 'UnitTestsAhuacatlVertex3/v5', 'inbound' , [{'what' : 'v2->v5'}]) SORT e.what RETURN e.what"); actual = getQueryResults("FOR e IN GRAPH_EDGES('bla3', 'UnitTestsAhuacatlVertex3/v5', 'inbound' , [{'what' : 'v2->v5'}]) SORT e.what RETURN e.what");
assertEqual(actual, [ "v2->v5" ]); assertEqual(actual, [ "v2->v5" ]);
actual = getQueryResults("FOR e IN GRAPH_NEIGHBORS('bla3', 'UnitTestsAhuacatlVertex3/v5', 'inbound' , [{'what' : 'v2->v5'}]) SORT e.what RETURN e");
assertEqual(actual[0].edge.what , "v2->v5");
assertEqual(actual[0].vertex._key , "v2");
}, },
@ -163,6 +170,12 @@ function ahuacatlQueryGeneralEdgesTestSuite() {
actual = getQueryResults("FOR e IN GRAPH_EDGES('bla3', 'UnitTestsAhuacatlVertex1/v1', 'outbound' , [{'what' : 'v2->v5'}]) SORT e.what RETURN e.what"); actual = getQueryResults("FOR e IN GRAPH_EDGES('bla3', 'UnitTestsAhuacatlVertex1/v1', 'outbound' , [{'what' : 'v2->v5'}]) SORT e.what RETURN e.what");
assertEqual(actual, []); assertEqual(actual, []);
actual = getQueryResults("FOR e IN GRAPH_NEIGHBORS('bla3', 'UnitTestsAhuacatlVertex1/v1', 'outbound') SORT e.what RETURN e");
assertEqual(actual[0].edge.what , "v1->v2");
assertEqual(actual[0].vertex._key , "v2");
assertEqual(actual[1].edge.what , "v1->v5");
assertEqual(actual[1].vertex._key , "v5");
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -353,7 +366,7 @@ function ahuacatlQueryGeneralPathsTestSuite() {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief test suite for GRAPH_TRAVERSAL() function /// @brief test suite for GRAPH_TRAVERSAL() and GRAPH_SHORTEST_PATH function
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
function ahuacatlQueryGeneralTraversalTestSuite() { function ahuacatlQueryGeneralTraversalTestSuite() {
@ -494,6 +507,23 @@ function ahuacatlQueryGeneralTraversalTestSuite() {
assertTrue(middle.connected.length === 1); assertTrue(middle.connected.length === 1);
assertEqual(middle.connected[0]._key, "Fritz"); assertEqual(middle.connected[0]._key, "Fritz");
},
testGRAPH_SHORTEST_PATH: function () {
var actual, result= [];
actual = getQueryResults("FOR e IN GRAPH_SHORTEST_PATH('werKenntWen', 'UnitTests_Hamburger/Caesar', 'UnitTests_Frankfurter/Emil', 'outbound') RETURN e");
actual.forEach(function (s) {
result.push(s.vertex._key);
});
assertEqual(result, [
"Caesar",
"Berta",
"Gerda",
"Dieter",
"Emil"
]);
} }
} }
} }