问题
I'm trying to get visualizations using d3.js or alchemy.js--but alchemy, in particular, requires the datasource to be in GraphJSON.
I've been playing around with the tutorials and examples of Max De Marzi (using neography), Michael Hunger (cy2neo, js), Neo4j, and Neo4j.rb -- but I cannot seem to get all the way there. Mostly because I don't know what I'm doing--but this is how I'm trying to learn.
What I'm trying to achieve would be along the lines of: https://bl.ocks.org/mbostock/3750558 or the default visualization here: http://graphalchemist.github.io/Alchemy/#/docs
And you can see what GraphJSON formatting should look like by finding it on this page also: http://graphalchemist.github.io/Alchemy/#/docs
If I run the following...
get '/followers' do
Neo4j::Session.open(:server_db, "http://localhost:7474")
query = Neo4j::Session.query('MATCH (a--(b)--(c) RETURN a,b,c LIMIT 30')
puts "--------------"
puts query_to_graph_json(query)
query_to_graph_json(query)
end
# This is supposed to grab nodes and edges, but it never gets edges.
# It's originally from a conversation at the neo4j.rb site
def query_to_graph_json(query)
nodes = {}
edges = {}
add_datum = Proc.new do |datum|
case datum
when Neo4j::ActiveNode, Neo4j::Server::CypherNode
nodes[datum.neo_id] = {
id: datum.neo_id,
properties: datum.props #was attributes, but kept saying that wasn't a method
}
when Neo4j::ActiveRel, Neo4j::Server::CypherRelationship
edges[[datum.start_node.neo_id, datum.end_node.neo_id]] = {
source: datum.start_node.neo_id,
target: datum.end_node.neo_id,
type: datum.rel_type,
properties: datum.props
}
else
raise "Invalid value found: #{datum.inspect}"
end
end
query.each do |row|
row.to_a.each do |datum|
if datum.is_a?(Array)
datum.each {|d| add_datum.call(d) }
else
add_datum.call(datum)
end
end
end
{
nodes: nodes.values,
edges: edges.values
}.to_json
end
I'll get...
{
"nodes": [
{
"id": 597,
"properties": {
"name": "John",
"type": "Person"
}
},
{
"id": 127,
"properties": {
"name": "Chris",
"type": "Person"
}
},
{
"id": 129,
"properties": {
"name": "Suzie",
"type": "Person"
}
},
],
"edges": [
]
}
The problem being that I need the edges.
If I run...
get '/followers' do
content_type :json
neo = Neography::Rest.new("http://localhost:7474")
cypher = "MATCH (a)--(b)--(c) RETURN ID(a),a.name,ID(b),b.name,ID(c),c.name LIMIT 30"
puts neo.execute_query(cypher).to_json
end
I'll get a table of paths. But it's not formatted in the way I need--and I have no idea how it might get from this format to the GraphJSON format.
{
"columns": [
"ID(a)",
"a.name",
"ID(b)",
"b.name",
"ID(c)",
"c.name"
],
"data": [
[
597,
"John",
127,
"Chris",
129,
"Suzie"
],
[
597,
"John",
6,
"Adam",
595,
"Pee-Wee"
]
]
}
回答1:
I think that one problem that you're having is that, instead of matching two nodes and one relationship, you're matching three nodes and two relationships. Here's your MATCH
:
MATCH (a)--(b)--(c)
It should be like:
MATCH (a)-[b]-(c)
In a MATCH
clause the []
can be excluded and you can just do a raw --
(or -->
or <--
) which represents the relationship.
You probably want to be querying for one specific direction though. If you query bidirectionally you'll get the same relationship twice with the start and end nodes switched.
Using neo4j-core
(which I biased towards as one of the maintainers ;)
nodes = []
rels = []
session.query('(source)-[rel]->(target)').pluck(:source, :rel, :target).each do |source, rel, target|
nodes << source
nodes << target
rels << rel
end
{
nodes: nodes,
edges: rels
}.to_json
Also note that if you don't specify any labels your query might be slow, depending on the number of nodes). Depends on what you need ;)
回答2:
This Cypher query should return the edges array as per the example format:
MATCH (a)-[r]-(b)
WITH collect(
{
source: id(a),
target: id(b),
caption: type(r)
}
) AS edges
RETURN edges
Running this against some sample data, the results look like this:
[
{
"source": 9456,
"target": 9454,
"caption": "LIKES"
},
{
"source": 9456,
"target": 9454,
"caption": "LIKES"
},
{
"source": 9456,
"target": 9455,
"caption": "LIKES"
},
{
"source": 9454,
"target": 9456,
"caption": "LIKES"
}
]
来源:https://stackoverflow.com/questions/35277838/from-neo4j-to-graphjson-with-ruby