Skip to content
Snippets Groups Projects
Unverified Commit 238bf16e authored by jimingquan's avatar jimingquan Committed by GitHub
Browse files

datacollect pathprop (#1027)

* datacollect pathprop

* address compiler error

* add unit test case

* fix error
parent c41b73e9
No related branches found
No related tags found
No related merge requests found
......@@ -49,6 +49,10 @@ folly::Future<Status> DataCollectExecutor::doCollect() {
NG_RETURN_IF_ERROR(collectMultiplePairShortestPath(vars));
break;
}
case DataCollect::DCKind::kPathProp: {
NG_RETURN_IF_ERROR(collectPathProp(vars));
break;
}
default:
LOG(FATAL) << "Unknown data collect type: " << static_cast<int64_t>(dc->kind());
}
......@@ -265,5 +269,75 @@ Status DataCollectExecutor::collectMultiplePairShortestPath(const std::vector<st
return Status::OK();
}
Status DataCollectExecutor::collectPathProp(const std::vector<std::string>& vars) {
DataSet ds;
ds.colNames = colNames_;
DCHECK(!ds.colNames.empty());
// 0: vertices's props, 1: Edges's props 2: paths without prop
DCHECK_EQ(vars.size(), 3);
auto vIter = ectx_->getResult(vars[0]).iter();
std::unordered_map<Value, Vertex> vertexMap;
vertexMap.reserve(vIter->size());
DCHECK(vIter->isPropIter());
for (; vIter->valid(); vIter->next()) {
const auto& vertexVal = vIter->getVertex();
if (!vertexVal.isVertex()) {
continue;
}
const auto& vertex = vertexVal.getVertex();
vertexMap.insert(std::make_pair(vertex.vid, std::move(vertex)));
}
auto eIter = ectx_->getResult(vars[1]).iter();
std::unordered_map<std::tuple<Value, EdgeType, EdgeRanking, Value>, Edge> edgeMap;
edgeMap.reserve(eIter->size());
DCHECK(eIter->isPropIter());
for (; eIter->valid(); eIter->next()) {
auto edgeVal = eIter->getEdge();
if (!edgeVal.isEdge()) {
continue;
}
auto& edge = edgeVal.getEdge();
auto edgeKey = std::make_tuple(edge.src, edge.type, edge.ranking, edge.dst);
edgeMap.insert(std::make_pair(std::move(edgeKey), std::move(edge)));
}
auto pIter = ectx_->getResult(vars[2]).iter();
DCHECK(pIter->isSequentialIter());
for (; pIter->valid(); pIter->next()) {
auto& pathVal = pIter->getColumn(0);
if (!pathVal.isPath()) {
continue;
}
auto path = pathVal.getPath();
auto src = path.src.vid;
auto found = vertexMap.find(src);
if (found != vertexMap.end()) {
path.src = found->second;
}
for (auto& step : path.steps) {
auto dst = step.dst.vid;
step.dst = vertexMap[dst];
auto type = step.type;
auto ranking = step.ranking;
if (type < 0) {
dst = src;
src = step.dst.vid;
type = -type;
}
auto edgeKey = std::make_tuple(src, type, ranking, dst);
auto edge = edgeMap[edgeKey];
step.props = edge.props;
src = step.dst.vid;
}
ds.rows.emplace_back(Row({std::move(path)}));
}
VLOG(2) << "Path with props : \n" << ds;
result_.setDataSet(std::move(ds));
return Status::OK();
}
} // namespace graph
} // namespace nebula
......@@ -33,6 +33,8 @@ private:
Status collectMultiplePairShortestPath(const std::vector<std::string>& vars);
Status collectPathProp(const std::vector<std::string>& vars);
std::vector<std::string> colNames_;
Value result_;
};
......
......@@ -130,6 +130,54 @@ protected:
.iter(Iterator::Kind::kGetNeighbors)
.finish());
}
{
// for path with prop
// <("0")-[:like]->("1")>
DataSet vertices;
vertices.colNames = {kVid, "player.name", "player.age"};
for (auto i = 0; i < 2; ++i) {
Row row;
row.values.emplace_back(folly::to<std::string>(i));
row.values.emplace_back(folly::to<std::string>(i));
row.values.emplace_back(i + 20);
vertices.rows.emplace_back(std::move(row));
}
qctx_->symTable()->newVariable("vertices");
qctx_->ectx()->setResult("vertices",
ResultBuilder()
.value(Value(std::move(vertices)))
.iter(Iterator::Kind::kProp)
.finish());
DataSet edges;
edges.colNames = {
"like._src", "like._dst", "like._rank", "like._type", "like.likeness"};
Row edge;
edge.values.emplace_back("0");
edge.values.emplace_back("1");
edge.values.emplace_back(0);
edge.values.emplace_back(15);
edge.values.emplace_back(90);
edges.rows.emplace_back(std::move(edge));
qctx_->symTable()->newVariable("edges");
qctx_->ectx()->setResult("edges",
ResultBuilder()
.value(Value(std::move(edges)))
.iter(Iterator::Kind::kProp)
.finish());
DataSet paths;
paths.colNames = {"paths"};
Vertex src("0", {});
Vertex dst("1", {});
Step step(std::move(dst), 15, "like", 0, {});
Path path(std::move(src), {step});
Row row;
row.values.emplace_back(std::move(path));
paths.rows.emplace_back(std::move(row));
qctx_->symTable()->newVariable("paths");
qctx_->ectx()->setResult("paths",
ResultBuilder().value(Value(std::move(paths))).finish());
}
}
protected:
......@@ -226,5 +274,30 @@ TEST_F(DataCollectTest, EmptyResult) {
EXPECT_EQ(result.value().getDataSet(), expected);
EXPECT_EQ(result.state(), Result::State::kSuccess);
}
TEST_F(DataCollectTest, PathWithProp) {
auto* dc = DataCollect::make(qctx_.get(), DataCollect::DCKind::kPathProp);
dc->setInputVars({"vertices", "edges", "paths"});
dc->setColNames({"paths"});
auto dcExe = std::make_unique<DataCollectExecutor>(dc, qctx_.get());
auto future = dcExe->execute();
auto status = std::move(future).get();
EXPECT_TRUE(status.ok());
auto& result = qctx_->ectx()->getResult(dc->outputVar());
DataSet expected;
expected.colNames = {"paths"};
Vertex src("0", {Tag("player", {{"age", Value(20)}, {"name", Value("0")}})});
Vertex dst("1", {Tag("player", {{"age", Value(21)}, {"name", Value("1")}})});
Step step(std::move(dst), 15, "like", 0, {{"likeness", 90}});
Path path(std::move(src), {std::move(step)});
Row row;
row.values.emplace_back(std::move(path));
expected.rows.emplace_back(std::move(row));
EXPECT_EQ(result.value().getDataSet(), expected);
EXPECT_EQ(result.state(), Result::State::kSuccess);
}
} // namespace graph
} // namespace nebula
......@@ -476,6 +476,10 @@ std::unique_ptr<PlanNodeDescription> DataCollect::explain() const {
addDescription("kind", "Multiple Pair Shortest", desc.get());
break;
}
case DCKind::kPathProp: {
addDescription("kind", "PathProp", desc.get());
break;
}
}
return desc;
}
......
......@@ -940,6 +940,7 @@ public:
kBFSShortest,
kAllPaths,
kMultiplePairShortest,
kPathProp,
};
static DataCollect* make(QueryContext* qctx, DCKind kind) {
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment