mirror of https://gitee.com/bigwinds/arangodb
Added edgeExamples functionality to CPPonly Neighbors.
This commit is contained in:
parent
1ae50e026c
commit
84174aa99a
|
@ -1582,7 +1582,7 @@ static AqlValue VertexIdsToAqlValue (triagens::arango::AqlTransaction* trx,
|
||||||
CollectionNameResolver const* resolver,
|
CollectionNameResolver const* resolver,
|
||||||
std::unordered_set<VertexId>& ids,
|
std::unordered_set<VertexId>& ids,
|
||||||
bool includeData = false) {
|
bool includeData = false) {
|
||||||
Json* result = new Json(Json::Array);
|
Json* result = new Json(Json::Array, ids.size());
|
||||||
|
|
||||||
if (includeData) {
|
if (includeData) {
|
||||||
for (auto& it : ids) {
|
for (auto& it : ids) {
|
||||||
|
@ -1609,7 +1609,7 @@ AqlValue Functions::Neighbors (triagens::aql::Query* query,
|
||||||
basics::traverser::NeighborsOptions opts;
|
basics::traverser::NeighborsOptions opts;
|
||||||
|
|
||||||
if (n < 4 || n > 6) {
|
if (n < 4 || n > 6) {
|
||||||
THROW_ARANGO_EXCEPTION_PARAMS(TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "NEIGHBORS");
|
THROW_ARANGO_EXCEPTION_PARAMS(TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "NEIGHBORS", (int) 4, (int) 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto resolver = trx->resolver();
|
auto resolver = trx->resolver();
|
||||||
|
@ -1654,9 +1654,30 @@ AqlValue Functions::Neighbors (triagens::aql::Query* query,
|
||||||
opts.start = v;
|
opts.start = v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (vertexInfo.isObject()) {
|
||||||
|
if (!vertexInfo.has("_id")) {
|
||||||
|
THROW_ARANGO_EXCEPTION_PARAMS(TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEIGHBORS");
|
||||||
|
}
|
||||||
|
vertexId = basics::JsonHelper::getStringValue(vertexInfo.get("_id").json(), "");
|
||||||
|
// TODO tmp can be replaced by Traversal::IdStringToVertexId
|
||||||
|
size_t split;
|
||||||
|
char const* str = vertexId.c_str();
|
||||||
|
|
||||||
|
if (! TRI_ValidateDocumentIdKeyGenerator(str, &split)) {
|
||||||
|
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_KEY_BAD);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string const collectionName = vertexId.substr(0, split);
|
||||||
|
auto coli = resolver->getCollectionStruct(collectionName);
|
||||||
|
if (coli == nullptr || collectionName.compare(vColName) != 0) {
|
||||||
|
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND);
|
||||||
|
}
|
||||||
|
VertexId v(coli->_cid, const_cast<char*>(str + split + 1));
|
||||||
|
opts.start = v;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
// TODO FIXME
|
// TODO FIXME
|
||||||
THROW_ARANGO_EXCEPTION_PARAMS(TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "NEIGHBORS");
|
THROW_ARANGO_EXCEPTION_PARAMS(TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEIGHBORS");
|
||||||
}
|
}
|
||||||
|
|
||||||
Json direction = ExtractFunctionParameter(trx, parameters, 3, false);
|
Json direction = ExtractFunctionParameter(trx, parameters, 3, false);
|
||||||
|
@ -1681,9 +1702,6 @@ AqlValue Functions::Neighbors (triagens::aql::Query* query,
|
||||||
THROW_ARANGO_EXCEPTION_PARAMS(TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "NEIGHBORS");
|
THROW_ARANGO_EXCEPTION_PARAMS(TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "NEIGHBORS");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ignored for now
|
|
||||||
auto examples = ExtractFunctionParameter(trx, parameters, 4, false);
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool includeData = false;
|
bool includeData = false;
|
||||||
|
|
||||||
|
@ -1700,26 +1718,8 @@ AqlValue Functions::Neighbors (triagens::aql::Query* query,
|
||||||
} else {
|
} else {
|
||||||
opts.maxDepth = basics::JsonHelper::getNumericValue<uint64_t>(options.json(), "maxDepth", opts.minDepth);
|
opts.maxDepth = basics::JsonHelper::getNumericValue<uint64_t>(options.json(), "maxDepth", opts.minDepth);
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if (options.has("includeData")) {
|
|
||||||
Json incl = options.get("includeData");
|
|
||||||
if (! incl.isBoolean() ) {
|
|
||||||
//TODO Correct Error Message
|
|
||||||
THROW_ARANGO_EXCEPTION_PARAMS(TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "NEIGHBORS");
|
|
||||||
}
|
|
||||||
includeData = incl.json()->_value._boolean;
|
|
||||||
}
|
|
||||||
if (options.has("minDepth")) {
|
|
||||||
Json min = options.get("minDepth");
|
|
||||||
}
|
|
||||||
if (options.has("maxDepth")) {
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Parse VertexInfo {_id},"v/1","1" are all valid
|
|
||||||
|
|
||||||
|
|
||||||
std::unordered_set<VertexId> neighbors;
|
std::unordered_set<VertexId> neighbors;
|
||||||
|
|
||||||
std::vector<EdgeCollectionInfo*> edgeCollectionInfos;
|
std::vector<EdgeCollectionInfo*> edgeCollectionInfos;
|
||||||
|
@ -1733,12 +1733,24 @@ AqlValue Functions::Neighbors (triagens::aql::Query* query,
|
||||||
};
|
};
|
||||||
|
|
||||||
TRI_voc_cid_t eCid = resolver->getCollectionId(eColName);
|
TRI_voc_cid_t eCid = resolver->getCollectionId(eColName);
|
||||||
|
|
||||||
|
|
||||||
|
// Function to return constant distance
|
||||||
auto wc = [](TRI_doc_mptr_copy_t& edge) -> double { return 1; };
|
auto wc = [](TRI_doc_mptr_copy_t& edge) -> double { return 1; };
|
||||||
edgeCollectionInfos.emplace_back(new EdgeCollectionInfo(
|
EdgeCollectionInfo* eci = new EdgeCollectionInfo(
|
||||||
eCid,
|
eCid,
|
||||||
trx->documentCollection(eCid),
|
trx->documentCollection(eCid),
|
||||||
wc
|
wc
|
||||||
));
|
);
|
||||||
|
|
||||||
|
edgeCollectionInfos.emplace_back(eci);
|
||||||
|
|
||||||
|
if (n > 4) {
|
||||||
|
auto edgeExamples = ExtractFunctionParameter(trx, parameters, 4, false);
|
||||||
|
if (! (edgeExamples.isArray() && edgeExamples.size() == 0) ) {
|
||||||
|
opts.addEdgeFilter(edgeExamples, eci->getShaper(), eCid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TRI_RunNeighborsSearch(
|
TRI_RunNeighborsSearch(
|
||||||
edgeCollectionInfos,
|
edgeCollectionInfos,
|
||||||
|
|
|
@ -293,6 +293,7 @@ void BasicOptions::addEdgeFilter (v8::Isolate* isolate,
|
||||||
TRI_shaper_t* shaper,
|
TRI_shaper_t* shaper,
|
||||||
TRI_voc_cid_t const& cid,
|
TRI_voc_cid_t const& cid,
|
||||||
string& errorMessage) {
|
string& errorMessage) {
|
||||||
|
useEdgeFilter = true;
|
||||||
auto it = _edgeFilter.find(cid);
|
auto it = _edgeFilter.find(cid);
|
||||||
|
|
||||||
if (example->IsArray()) {
|
if (example->IsArray()) {
|
||||||
|
@ -308,6 +309,20 @@ void BasicOptions::addEdgeFilter (v8::Isolate* isolate,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief Insert a new edge matcher object
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void BasicOptions::addEdgeFilter (Json const& example,
|
||||||
|
TRI_shaper_t* shaper,
|
||||||
|
TRI_voc_cid_t const& cid) {
|
||||||
|
useEdgeFilter = true;
|
||||||
|
auto it = _edgeFilter.find(cid);
|
||||||
|
if (it == _edgeFilter.end()) {
|
||||||
|
_edgeFilter.emplace(cid, new ExampleMatcher(example.json(), shaper));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief Checks if an edge matches to given examples
|
/// @brief Checks if an edge matches to given examples
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -171,6 +171,10 @@ namespace triagens {
|
||||||
TRI_voc_cid_t const& cid,
|
TRI_voc_cid_t const& cid,
|
||||||
std::string& errorMessage);
|
std::string& errorMessage);
|
||||||
|
|
||||||
|
void addEdgeFilter (Json const& example,
|
||||||
|
TRI_shaper_t* shaper,
|
||||||
|
TRI_voc_cid_t const& cid);
|
||||||
|
|
||||||
void addVertexFilter (v8::Isolate* isolate,
|
void addVertexFilter (v8::Isolate* isolate,
|
||||||
v8::Handle<v8::Value> const& example,
|
v8::Handle<v8::Value> const& example,
|
||||||
triagens::arango::ExplicitTransaction* trx,
|
triagens::arango::ExplicitTransaction* trx,
|
||||||
|
|
|
@ -76,6 +76,9 @@ namespace triagens {
|
||||||
TRI_shaper_t* _shaper;
|
TRI_shaper_t* _shaper;
|
||||||
std::vector<ExampleDefinition> definitions;
|
std::vector<ExampleDefinition> definitions;
|
||||||
|
|
||||||
|
void fillExampleDefinition (TRI_json_t const* example,
|
||||||
|
ExampleDefinition& def);
|
||||||
|
|
||||||
void fillExampleDefinition (v8::Isolate* isolate,
|
void fillExampleDefinition (v8::Isolate* isolate,
|
||||||
v8::Handle<v8::Object> const& example,
|
v8::Handle<v8::Object> const& example,
|
||||||
v8::Handle<v8::Array> const& names,
|
v8::Handle<v8::Array> const& names,
|
||||||
|
@ -95,7 +98,7 @@ namespace triagens {
|
||||||
TRI_shaper_t* shaper,
|
TRI_shaper_t* shaper,
|
||||||
std::string& errorMessage);
|
std::string& errorMessage);
|
||||||
|
|
||||||
ExampleMatcher (TRI_json_t* example,
|
ExampleMatcher (TRI_json_t const* example,
|
||||||
TRI_shaper_t* shaper);
|
TRI_shaper_t* shaper);
|
||||||
|
|
||||||
~ExampleMatcher () {
|
~ExampleMatcher () {
|
||||||
|
|
|
@ -172,6 +172,58 @@ function ahuacatlQueryEdgesTestSuite () {
|
||||||
assertEqual(actual, [ ]);
|
assertEqual(actual, [ ]);
|
||||||
|
|
||||||
assertQueryError(errors.ERROR_ARANGO_COLLECTION_NOT_FOUND.code, "FOR e IN EDGES(UnitTestsAhuacatlEdge, 'thefox/thefox', 'outbound') SORT e.what RETURN e.what");
|
assertQueryError(errors.ERROR_ARANGO_COLLECTION_NOT_FOUND.code, "FOR e IN EDGES(UnitTestsAhuacatlEdge, 'thefox/thefox', 'outbound') SORT e.what RETURN e.what");
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function ahuacatlQueryNeighborsTestSuite () {
|
||||||
|
var vertex = null;
|
||||||
|
var edge = null;
|
||||||
|
|
||||||
|
return {
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief set up
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
setUp : function () {
|
||||||
|
db._drop("UnitTestsAhuacatlVertex");
|
||||||
|
db._drop("UnitTestsAhuacatlEdge");
|
||||||
|
|
||||||
|
vertex = db._create("UnitTestsAhuacatlVertex");
|
||||||
|
edge = db._createEdgeCollection("UnitTestsAhuacatlEdge");
|
||||||
|
|
||||||
|
vertex.save({ _key: "v1", name: "v1" });
|
||||||
|
vertex.save({ _key: "v2", name: "v2" });
|
||||||
|
vertex.save({ _key: "v3", name: "v3" });
|
||||||
|
vertex.save({ _key: "v4", name: "v4" });
|
||||||
|
vertex.save({ _key: "v5", name: "v5" });
|
||||||
|
vertex.save({ _key: "v6", name: "v6" });
|
||||||
|
vertex.save({ _key: "v7", name: "v7" });
|
||||||
|
|
||||||
|
function makeEdge (from, to) {
|
||||||
|
edge.save("UnitTestsAhuacatlVertex/" + from, "UnitTestsAhuacatlVertex/" + to, { what: from + "->" + to, _key: from + "_" + to });
|
||||||
|
}
|
||||||
|
|
||||||
|
makeEdge("v1", "v2");
|
||||||
|
makeEdge("v1", "v3");
|
||||||
|
makeEdge("v2", "v3");
|
||||||
|
makeEdge("v3", "v4");
|
||||||
|
makeEdge("v3", "v6");
|
||||||
|
makeEdge("v3", "v7");
|
||||||
|
makeEdge("v4", "v2");
|
||||||
|
makeEdge("v7", "v3");
|
||||||
|
makeEdge("v6", "v3");
|
||||||
|
},
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief tear down
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
tearDown : function () {
|
||||||
|
db._drop("UnitTestsAhuacatlVertex");
|
||||||
|
db._drop("UnitTestsAhuacatlEdge");
|
||||||
},
|
},
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -327,6 +379,44 @@ function ahuacatlQueryEdgesTestSuite () {
|
||||||
return x.name;
|
return x.name;
|
||||||
});
|
});
|
||||||
assertEqual(actual, ["v4", "v6", "v7"]);
|
assertEqual(actual, ["v4", "v6", "v7"]);
|
||||||
|
},
|
||||||
|
|
||||||
|
testNeighborsEdgeExamples : function () {
|
||||||
|
var actual;
|
||||||
|
var v3 = "UnitTestsAhuacatlVertex/v3";
|
||||||
|
var v4 = "UnitTestsAhuacatlVertex/v4";
|
||||||
|
var v6 = "UnitTestsAhuacatlVertex/v6";
|
||||||
|
var v7 = "UnitTestsAhuacatlVertex/v7";
|
||||||
|
var query = "FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, @startId"
|
||||||
|
+ ", 'outbound', @examples) SORT n RETURN n";
|
||||||
|
|
||||||
|
// An empty array should let all edges through
|
||||||
|
actual = getQueryResults(query, {startId: v3, examples: []});
|
||||||
|
assertEqual(actual, [ v4, v6, v7 ]);
|
||||||
|
|
||||||
|
// Should be able to handle exactly one object
|
||||||
|
actual = getQueryResults(query, {startId: v3, examples: {what: "v3->v4"}});
|
||||||
|
assertEqual(actual, [ v4 ]);
|
||||||
|
|
||||||
|
// Should be able to handle a list of a single object
|
||||||
|
actual = getQueryResults(query, {startId: v3, examples: [{what: "v3->v4"}]});
|
||||||
|
assertEqual(actual, [ v4 ]);
|
||||||
|
|
||||||
|
// Should be able to handle a list of objects
|
||||||
|
actual = getQueryResults(query, {startId: v3, examples: [{what: "v3->v4"}, {what: "v3->v6"}]});
|
||||||
|
assertEqual(actual, [ v4, v6 ]);
|
||||||
|
|
||||||
|
// Should be able to handle an id as string
|
||||||
|
actual = getQueryResults(query, {startId: v3, examples: "UnitTestAhuacatlEdge/v3_v6"});
|
||||||
|
assertEqual(actual, [ v6 ]);
|
||||||
|
|
||||||
|
// Should be able to handle a mix of id and objects
|
||||||
|
actual = getQueryResults(query, {startId: v3, examples: ["UnitTestAhuacatlEdge/v3_v6", {what: "v3->v4"}]});
|
||||||
|
assertEqual(actual, [ v4, v6 ]);
|
||||||
|
|
||||||
|
// Should be able to handle internal attributes
|
||||||
|
actual = getQueryResults(query, {startId: v3, examples: {_to: v4}});
|
||||||
|
assertEqual(actual, [ v4 ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -1862,6 +1952,7 @@ function ahuacatlQueryShortestpathErrorsSuite () {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
jsunity.run(ahuacatlQueryEdgesTestSuite);
|
jsunity.run(ahuacatlQueryEdgesTestSuite);
|
||||||
|
jsunity.run(ahuacatlQueryNeighborsTestSuite);
|
||||||
jsunity.run(ahuacatlQueryPathsTestSuite);
|
jsunity.run(ahuacatlQueryPathsTestSuite);
|
||||||
jsunity.run(ahuacatlQueryShortestPathTestSuite);
|
jsunity.run(ahuacatlQueryShortestPathTestSuite);
|
||||||
jsunity.run(ahuacatlQueryTraversalFilterTestSuite);
|
jsunity.run(ahuacatlQueryTraversalFilterTestSuite);
|
||||||
|
|
Loading…
Reference in New Issue