我有以下示例图:
我的根节点为LV
,Map<Vertex, Vertex>
包含:
Map = {<A_T, A_V>, <B_T, B_V>, <C_T, C_V>, ... <N_T, N_V>}
我正在尝试创建一个从LV
开始的遍历并转到每个离开A_T, A_V, B_T, B_V, C_T, C_V
。最初我正在考虑构建我的遍历:
GraphTraversal traversal = graph().traversal().V(LV.id());
traversal.and(out().hasId(A_T.id(), A_V.id()),
out().hasId(B_T.id(), B_V.id()),
out().hasId(C_T.id(), C_V.id()),
...
out().hasId(N_T.id(), N_V.id()));
问题是.and(Object . . .)
无法动态添加(如我所知),N
可能是任何数字,所以有一次我想要:
traversal.and(out().hasId(A_T.id(), A_V.id()),
out().hasId(B_T.id(), B_V.id());
在另一个我想要的地方:
traversal.and(out().hasId(A_T.id(), A_V.id()),
out().hasId(B_T.id(), B_V.id()),
out().hasId(C_T.id(), C_V.id()),
out().hasId(D_T.id(), D_V.id()));
此遍历应该用作LV
与Map
中所有组件之间现有结构的验证。
有没有办法实现这项功能?
答案 0 :(得分:2)
让我们先创建示例图和地图:
# Setup
heroku plugins:install https://github.com/heroku/heroku-oauth
heroku authorizations:create -s write
heroku config:add RESTART_API_KEY=<API KEY>
heroku config:add APP_NAME=<App Name>
heroku addons:add scheduler:standard -a <App Name>
heroku addons:open scheduler -a <App Name>
add `rake restart`
# Gemfile
gem 'platform-api', require: false
# Rakefile
task :restart do
require 'platform-api'
app_name = ENV.fetch('APP_NAME')
key = ENV.fetch('RESTART_API_KEY')
connection = PlatformAPI.connect_oauth(key)
connection.dyno.list(app_name).map do |info|
if info['type'] == 'web' && info['state'] == 'up'
puts "Restarting #{info.inspect}"
connection.dyno.restart(app_name, info['name'])
else
puts "Skipping #{info.inspect}"
end
end
end
现在,要弄清楚是否可以找到结构,你可以这样做:
graph = TinkerGraph.open()
names = ["LV",
"A_C","A_T","A_V",
"B_C","B_T","B_V",
"C_C","C_T","C_V"]
vertices = names.collectEntries { def name ->
[name, graph.addVertex("name", name)]
}
vertices["LV"].addEdge("link", vertices["A_C"])
vertices["LV"].addEdge("link", vertices["B_C"])
vertices["LV"].addEdge("link", vertices["C_C"])
vertices["A_C"].addEdge("link", vertices["A_T"])
vertices["A_C"].addEdge("link", vertices["A_V"])
vertices["B_C"].addEdge("link", vertices["B_T"])
vertices["B_C"].addEdge("link", vertices["B_V"])
vertices["C_C"].addEdge("link", vertices["C_T"])
vertices["C_C"].addEdge("link", vertices["C_V"])
m = [:]
m.put(vertices["A_T"], vertices["A_V"])
m.put(vertices["B_T"], vertices["B_V"])
m.put(vertices["C_T"], vertices["C_V"])
这是Gremlin控制台的结果:
leafs = m.keySet() + m.values()
g = graph.traversal()
found = g.V(vertices["LV"]).out().out().fold().
where(count(local).is(m.size() << 1)).
not(unfold().is(without(leafs))).hasNext()
如果我们在地图上添加一些项目,那么这不是结构的一部分:
gremlin> found = g.V(vertices["LV"]).out().out().fold().
gremlin> where(count(local).is(m.size() << 1)).
gremlin> not(unfold().is(without(leafs))).hasNext()
==>true
答案 1 :(得分:0)
解决了它。一如既往,我会为可能遇到类似问题的人发布我的解决方案。
问题是and(...)
方法可以采用多个参数。所以我可以动态构造最终的遍历。具体来说,我可以做到以下几点。
public void awesomeTraversal(Vertex LV, Map<Vertex, Vertex> vertexMap){
GraphTraversal<Vertex, Vertex> traversal = graph.traversal().V(LV.id()); //Start at LV
ArrayList<GraphTraversal> innerTraversals = new ArrayList<>();
for(Map.Entry<Vertex, Vertex> v : vertexMap){
// Check you can go to X_T
innerTraversals.add(__.out().out().is(entry.getKey()));
//Check you can go to X_V
innerTraversals.add(__.out().out().is(entry.getValue()));
}
//Filter via and.
traversal = traversal.and(innerTraversal.toArray(GraphTraversal[innerTraversals.size()]));
if(traversal.hasNext()){
System.out.println("Found structure");
} else {
System.out.println("No structure");
}
}
这似乎对我有用。任何改进都将非常受欢迎。