Cypher iterate through all returned nodes AND get ALL properties of the nodes

3,626 views
Skip to first unread message

Rich Westington

unread,
Dec 28, 2011, 3:13:00 AM12/28/11
to ne...@googlegroups.com
In this code snippet, is it possible to iterate through all the nodes in the variable result and get ALL properties of the node just by saying node.getProperty("the_property")
Keep in mind, I DONT want to have to explicitly say RETURN x.this_property, x.that_property, x.last_property 

    CypherParser parser = new CypherParser();
    ExecutionEngine engine = new ExecutionEngine( graphDb );
    // I dont like how I have to explicitly say what properties I want returned
    Query query = parser.parse( "START n=node(2) MATCH (n)<-[:IS_A]-(x) RETURN x" );
    ExecutionResult result = engine.execute( query );
    // how do I iterate through nodes and get all their properties

I want to be able to do exactly the equivalent of this other code below, but using Cypher.
    
    // I like how I don't have to say what properties I want returned, it just returns them all
    Traverser traverser = graphDb.getNodeById(2).traverse(
        Order.BREADTH_FIRST,
        StopEvaluator.END_OF_GRAPH,
        ReturnableEvaluator.ALL_BUT_START_NODE,
        RelTypes.IS_A,
        Direction.INCOMING
    );
    
    for ( Node node : traverser ) {
        TraversalPosition position = traverser.currentPosition();
        // I like how I can get any property just by saying node.getProperty("whatever_the_property_is")
        System.out.println(  node.getProperty( "name" ) );
    }


Peter Neubauer

unread,
Dec 28, 2011, 3:32:06 AM12/28/11
to ne...@googlegroups.com
Wow,
I don't think you can do that right now. However, that sounds
interesting! Maybe something like the collect function could be used
for that?

START n = node(0)
RETURN collect(n./*name*/)

or so?

Cheers,

/peter neubauer

Google:neubauer.peter
Skype:peter.neubauer
Phone: +46 704 106975
LinkedIn   http://www.linkedin.com/in/neubauer
Twitter      @peterneubauer

brew install neo4j && neo4j start
heroku addons:add neo4j

Andres Taylor

unread,
Dec 28, 2011, 4:05:23 AM12/28/11
to ne...@googlegroups.com
On Wed, Dec 28, 2011 at 9:32 AM, Peter Neubauer <peter.n...@neotechnology.com> wrote:
Wow,
I don't think you can do that right now. However, that sounds
interesting! Maybe something like the collect function could be used
for that?

START n = node(0)
RETURN collect(n./*name*/) 

Collect here means that we won't know the property names, which is bad.

I've been thinking about adding something like this:

START n=node(0)
RETURN n.* 

That would return all properties in the node. The problem is that since we are schema-less, we wouldn't know until run-time which columns are part of the query, which may be a blocker...

WDYT?

Andrés

Rich Westington

unread,
Dec 28, 2011, 4:28:38 AM12/28/11
to ne...@googlegroups.com
That code was actually the first thing I tried

START n=node(0)
RETURN n.*

I'd want to be able to the same traversals in Cypher as I could in the Java API...
I'd also think that if someone wrote RETURN n.* then they would be expecting to use some columns and ignore other columns that are returned...
kinda just like how SQL feels... SELECT * FROM SQL_Table ... even though that with a fixed schema


I would definitely like to see something like RETURN n.* added though

Andres Taylor

unread,
Dec 28, 2011, 4:45:24 AM12/28/11
to Rickard Öberg, ne...@googlegroups.com
Rickard - what does the JDBC driver think about this?

Andrés

Rickard Öberg

unread,
Dec 28, 2011, 5:12:08 AM12/28/11
to Andres Taylor, ne...@googlegroups.com
Hi,

On Wed, Dec 28, 2011 at 5:45 PM, Andres Taylor <and...@neotechnology.com> wrote:
> Rickard - what does the JDBC driver think about this?
>
> Andrés

Yeah, I was reading the question and having the same thought. From a
JDBC point of view you really really do want to have schemas, even
though it is merely prototypical or prescriptive rather than absolute,
as in SQL.

I was gonna bring this up later anyway, so here is my take on it,
probably slightly longish (sorry).

What are schemas? On the most fundamental level schemas are languages.
We use languages to express things so that we can communicate. You can
understand what I write now because we use a shared language.
Languages are good. If we don't have languages, azhed faut ikl
sheeada. I.e. you have no frickin' idea what I'm saying.

In the relational world, every row must belong to a table, and every
table has a description of its columns, and every row has a value for
each column (including null, which is also a value, as it is not "I
don't know"). Everything is in one little box or another little box.

Comparatively, in the XML world, each document starts off as simply
existing, and then we can add languages to it by means of XML
namespaces, to mix and match things within the document container.
Similarly, in the real world we can mix languages, like swenglish,
manglish, or 1337 talk. RDF has similar characteristics, where a
URL/URI can have tuples about it from many ontologies, but it is
different from XML in the sense that there is more explicit support
for saying that a URI "is a type of" something.

Right now Neo4j has no schema support, i.e. it has no support for
languages. In other words, allura zhifo weart floo. It is easy to make
things not make any sense, and it is impossible to talk about things
in terms of patterns and concepts, as any language is inexpressible
and implicit.

Coming back to the initial question, for the purpose of JDBC, where
you can do a whole lot of work just talking about language, i.e.
schema, i.e. "what types are there and what do they look like", Neo4j
right now doesn't really help. It shows also in the sense that doing
things like * queries have no meaning. If a tool does "select * from
X" the JDBC driver currently has to first make a call to the server to
find my type node X, list the properties back as a result, and then
make another call where the properties are explicitly listed. If types
was something that was explicitly supported, then it would be much
much easier to talk about things on the metalevel. Because basically
using * is that: "I know that what I look for has type X, so gimme
everything related to type X".

Talking about being schema-less as being good I think is something
that is not the right thing to do. Languages are very useful. It's
just that languages/schemas in the relational sense, where you only
get to pick one at a time, is really not helpful. I like swenglish,
and manglish when appropriate. Considering the power of Neo4j to
construct arbitrary graphs, much like what you can do with XML and
RDF, I would suggest that that approach, whereby you do have languages
but they can be combined and used whenever appropriate, is the right
way to go. And it will help Cypher, and it will definitely help the
JDBC driver, as then you can talk about things without mentioning
explicit instances of things.

And taking a hint from RDF and XML, languages should of course be
expressed using graphs, in two levels: users can create languages
using the language language, and the language language (i.e. something
like XMLSchema) is then defined recursively, within Neo4j itself. So
at the root, you should be able to ask "gimme a list of all languages
in the database", and then continue from there.

Something like that.

/Rickard

Message has been deleted

Andres Taylor

unread,
Dec 28, 2011, 10:09:30 AM12/28/11
to ne...@googlegroups.com


On Wed, Dec 28, 2011 at 11:47 AM, Rich Westington <richwes...@gmail.com> wrote:
Oh, to add one more thing, it would also be great to be able to get all relationships or just any methods in the Node class here ... http://components.neo4j.org/neo4j/1.6.M02/apidocs/org/neo4j/graphdb/Node.html

I'm not clear on what you want. You can get all relationships - just add them to your pattern. Or am I missing something?

And what do you mean by "just any methods"? Cypher is a query language, and you are pointing to the Java API docs. What is the connection?

Andrés 

Rich Westington

unread,
Dec 28, 2011, 1:40:57 PM12/28/11
to ne...@googlegroups.com
Yeah, sorry, just disregard that other post, I was up all night till 5am writing that so I wasn't thinking clearly

Michael Hunger

unread,
Dec 28, 2011, 6:25:31 PM12/28/11
to ne...@googlegroups.com
Rich that should be no problem at all.

ExecutionResult is an iterator over all "rows" and for each row you get a Map<String,Object>.

so

for (Map<String,Object> row : result) {
   Node n = row.values().iterator().next();
  for (String prop : n.getPropertyKeys()) {
    System.out.println(n.getProperty(prop));
  }
}

HTH

Michael
Message has been deleted

Rich Westington

unread,
Dec 30, 2011, 10:45:03 PM12/30/11
to ne...@googlegroups.com
For some reason that code is throwing an error "Can only iterate over an array or an instance of java.lang.Iterable"
Are you sure ExecutionResult implements Iterable?

Andres Taylor

unread,
Dec 31, 2011, 6:02:49 AM12/31/11
to ne...@googlegroups.com


On Sat, Dec 31, 2011 at 4:45 AM, Rich Westington <richwes...@gmail.com> wrote:
For some reason that code is throwing an error "Can only iterate over an array or an instance of java.lang.Iterable"

Are you sure ExecutionResult implements Iterable?

There are two ExecutionResults - one in org.neo4j.cypher, and one in org.neo4j.cypher.javacompat.

Which one are you using?

Andrés

Rich Westington

unread,
Dec 31, 2011, 1:11:33 PM12/31/11
to ne...@googlegroups.com
I just switched to using the ExecutionResult in org.neo4j.cypher.javacompat and now it seems to be working, thanks!

lazyprogrammer

unread,
Jan 6, 2012, 12:45:22 AM1/6/12
to Neo4j
The code says "Type mismatch: cannot convert from Object to Node"
error. Could you please help me out in this matter

On Dec 31 2011, 11:11 pm, Rich Westington <richwesting...@gmail.com>
wrote:

Michael Hunger

unread,
Jan 6, 2012, 1:46:22 AM1/6/12
to ne...@googlegroups.com
Could you please provide your code and query

Von meinem iPhone gesendet

lazyprogrammer

unread,
Jan 6, 2012, 1:54:32 AM1/6/12
to Neo4j
The query was to find a node that was differentiated form other nodes
via property of the relationship instance connecting the node.
The query is like:
Query query = parser.parse("start n = node(*) match n-[r:**name}->m
where r.**prop = \"XYZ\" return m");
ExecutionResult result = engine.execute(query);

I am iterating over all the rows that are resulted from the query and
want to print all the properties of each node in the iteration

On Jan 6, 11:46 am, Michael Hunger <michael.hun...@neopersistence.com>
wrote:
> Could you please provide your code and query
>
> Von meinem iPhone gesendet
>

Michael Hunger

unread,
Jan 6, 2012, 2:00:42 AM1/6/12
to ne...@googlegroups.com
Please provide the iteration code.

lazyprogrammer

unread,
Jan 6, 2012, 2:01:36 AM1/6/12
to Neo4j
The iteration code was the one suggested above. i am not quite sure of
whether it will help me out but here it is:
for (Map<String,Object> row : result) {
Node n = row.values().iterator().next();
for (String prop : n.getPropertyKeys()) {
System.out.println(n.getProperty(prop));
}

}

On Jan 6, 12:00 pm, Michael Hunger <michael.hun...@neotechnology.com>
wrote:

Andres Taylor

unread,
Jan 6, 2012, 2:07:01 AM1/6/12
to ne...@googlegroups.com
On Fri, Jan 6, 2012 at 7:54 AM, lazyprogrammer <lazyprogr...@gmail.com> wrote:
Query query = parser.parse("start n = node(*) match n-[r:**name}->m
where r.**prop = \"XYZ\" return m");
ExecutionResult result = engine.execute(query);
 
This is not a valid query. [r:**name] makes no sense, and likewise r.**prop. And n=node(*) is also wrong. This can't even be parsing correctly, right?

What are you trying to do?

Andrés


lazyprogrammer

unread,
Jan 6, 2012, 2:13:47 AM1/6/12
to Neo4j
Oops sorry. The query is
Query query = parser.parse("start n = node(0) match n-[r:Fruit]->m
where r.Type = \"Soar\" return m";

Fruit is the relationship type and soar is the property of the Fruit
relationship type that differentiates the result m(results a set of
nodes) from other nodes. I regret for the above post.
Thank You.

On Jan 6, 12:07 pm, Andres Taylor <and...@neotechnology.com> wrote:
> On Fri, Jan 6, 2012 at 7:54 AM, lazyprogrammer <
>

Andres Taylor

unread,
Jan 6, 2012, 3:45:22 AM1/6/12
to ne...@googlegroups.com

Given this query:
start n = node(0) 
match n-[r:Fruit]->m
where r.Type = "Soar"
return m

 And this iterating of the results:

  Node n = row.values().iterator().next();
 for (String prop : n.getPropertyKeys()) {
   System.out.println(n.getProperty(prop));
 }

}

I don't see how this can give the error you claimed: "Type mismatch: cannot convert from Object to Node"

You are not giving us enough information for us to be able to help you.

Andrés


lazyprogrammer

unread,
Jan 6, 2012, 4:15:28 AM1/6/12
to Neo4j
Added a cast to the Node type in front of the row.values()... code and
it worked out. Thanks for the quick replies but that was what the
actual code was and Eclipse showed the error I queried in the group.

lazyprogrammer

unread,
Jan 6, 2012, 7:13:32 AM1/6/12
to Neo4j
Can I continue the query form there on with the resulted nodes(from
the above mentioned cypher query differentiating a node from others
with the help of property of relationship attached to the node) and
return all the nodes that are connected(not only immediate but to
infinite depth) to the resulted nodes in the above query(using cypher)?

Peter Neubauer

unread,
Jan 6, 2012, 7:30:15 AM1/6/12
to ne...@googlegroups.com
Yes,
look at http://docs.neo4j.org/chunked/snapshot/query-match.html#match-variable-length-relationships

Cheers,

/peter neubauer

Google:    neubauer.peter
Skype:     peter.neubauer
Phone:     +46 704 106975
LinkedIn:  http://www.linkedin.com/in/neubauer
Twitter:    @peterneubauer

Tungle:    tungle.me/peterneubauer

brew install neo4j && neo4j start
heroku addons:add neo4j

lazyprogrammer

unread,
Jan 9, 2012, 5:02:55 AM1/9/12
to Neo4j
I had tried to get all the nodes that are reachable via this node(upto
depth 2) and failed. My script was:

start n = node(0)
match n-[r:Fruit]->m,m-[?]->x,x-[?]->y
where r.Type="Soar"
return m,x,y

The above script returns nothing.Could you please help me out of this
trouble

Michael Hunger

unread,
Jan 9, 2012, 5:07:27 AM1/9/12
to ne...@googlegroups.com
Can you share your db?

Or at least the nodes for m and m with their properties and relationships (and the existing "r" - relationship(s)).

Michael

lazyprogrammer

unread,
Jan 9, 2012, 5:31:01 AM1/9/12
to Neo4j
My db consists of a reference node to which all fruits are directly
linked by the "Fruit" relationship type and differentiated from one
another by the "Type" property of the Fruit relationship type. One of
the sour fruit is lemon. This node consists of the name and color
properties. It has outgoing relationship types named Use,Nutritional
Value etc. The Use relationship type connects to two nodes with
names(as property of the nodes) Culinary Use and Non Culinary Use. Now
Culinary Use node has outgoing relationship type CU that connects to
nodes named Lemonade,SoftDrinks etc,. Non Culinary Use node has
outgoing relationship type NCU connecting the node named
Aromatherapy.
Reply all
Reply to author
Forward
0 new messages