relationship query help

36 views
Skip to first unread message

Chris Fitzpatrick

unread,
Aug 1, 2012, 9:37:30 AM8/1/12
to neo...@googlegroups.com
Hi,

I'm having a bit of trouble with a query...I'm wanting to find which
person has the most items attibuted to them.
Just to illustrate a bit...
neo4j-sh (0)$ START x = node(3) MATCH x - [r] - n RETURN type(r)
==> +-----------------------+
==> | type(r) |
==> +-----------------------+
==> | "Document#items" |
==> | "Document#items" |
==> | "Person#created_work" |
==> | "Person#created_work" |
==> | "_all" |
==> +-----------------------+

node(3) is a Document, with 2 authors related to Person#created_work

So, to find out which people have the most Person#created_work
relationships, I've wrote this query:

START n = node(*) MATCH n-[r:Person#created_work]->c RETURN n.name,
count(r) as connections ORDER BY connections DESC

but cypher doesn't seem to like the # in my relationship type. I've
tried putting it in quotes and escaping it, but nothing seems to do
the trick. I'm using the Neo4j::Rails::Relationship model, which is
naming the relationship type with based on the Model#method syntax....

Any suggestions? Thanks!

best, fitz.

Max De Marzi Jr.

unread,
Aug 1, 2012, 9:53:00 AM8/1/12
to neo...@googlegroups.com
Try backticks around the relationship type. 
--
You received this message because you are subscribed to the Google Groups "neo4jrb" group.
To post to this group, send email to neo...@googlegroups.com.
To unsubscribe from this group, send email to neo4jrb+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/neo4jrb?hl=en.

Chris Fitzpatrick

unread,
Aug 1, 2012, 11:14:00 AM8/1/12
to neo...@googlegroups.com
Hey,

Yeah, that seemed to do the trick...works great in the console...
however, it looks like it's not working with jruby..

jruby-1.6.7.2 :176 > q = Neo4j._query("START n = node(*) MATCH
n-[r:`Person#created_work`]->c RETURN n.name, count(r) as connections
ORDER BY connections DESC")
jruby-1.6.7.2 :177 > q.to_a
NativeException: java.lang.ClassCastException:
org.jruby.gen.InterfaceImpl1332573772 cannot be cast to
org.neo4j.kernel.GraphDatabaseAPI
from org/neo4j/tooling/GlobalGraphOperations.java:39:in `<init>'
from org/neo4j/tooling/GlobalGraphOperations.java:51:in `at'
from org/neo4j/cypher/internal/executionplan/builders/GraphGlobalStartBuilder.scala:45:in
`apply'
from org/neo4j/cypher/internal/executionplan/builders/GraphGlobalStartBuilder.scala:45:in
`apply'
from org/neo4j/cypher/internal/pipes/StartPipe.scala:38:in `apply'
from org/neo4j/cypher/internal/pipes/StartPipe.scala:37:in `apply'
from scala/collection/TraversableLike.scala:200:in `apply'
from scala/collection/TraversableLike.scala:200:in `apply'
from scala/collection/LinearSeqOptimized.scala:59:in `foreach'
from scala/collection/immutable/List.scala:45:in `foreach'
from scala/collection/TraversableLike.scala:200:in `flatMap'
from scala/collection/immutable/List.scala:45:in `flatMap'
from org/neo4j/cypher/internal/pipes/StartPipe.scala:37:in `createResults'
from org/neo4j/cypher/internal/pipes/MatchPipe.scala:32:in `createResults'
from org/neo4j/cypher/internal/pipes/ExtractPipe.scala:38:in `createResults'
from org/neo4j/cypher/internal/pipes/EagerAggregationPipe.scala:48:in
`createResults'


It looks like the node(*) is returning something that cannot be cast
as a ruby enumerable. If I change the node(*) to something like
node(3) I can iterate on it just fine...any suggestions how I can work
around this one?

Thanks again for all the help...b,fitz.

Michael Hunger

unread,
Aug 1, 2012, 11:20:51 AM8/1/12
to neo...@googlegroups.com
Chris,

which version of neo4jrb are you using? Seems that it has an issue (in the java-layer from what is passed in from neo4j.rb and what GlobalGraphOperations expects (GraphDatbaseAPI, which was introduced in 1.7)

Michael

Chris Fitzpatrick

unread,
Aug 1, 2012, 12:04:11 PM8/1/12
to neo...@googlegroups.com
Hi,

I'm actually pulling from the github head, right now, so I'm slightly
ahead of 2.0.1. Here are my other Neo4j gems in my project...

neo4j-admin (0.1.0-java)
neo4j-community (1.7.1-java)
neo4j-core (2.0.1-java)
neo4j-wrapper (2.0.1-java)

I also tried this query and it also raised the same errors:

engine = Java::OrgNeo4jCypherJavacompat::ExecutionEngine.new(Neo4j.db)
result = engine.execute("START n = node(*) MATCH
n-[r:`Person#created_work`]->c RETURN n.name, count(r) as connections
ORDER BY connections DESC")
result.first


also throws java.lang.ClassCastException .

Michael Hunger

unread,
Aug 1, 2012, 3:51:24 PM8/1/12
to neo...@googlegroups.com
there is some Neo4j.db.raw or similar method to get the original neo4j database back.

Michael

Chris Fitzpatrick

unread,
Aug 1, 2012, 6:17:14 PM8/1/12
to neo...@googlegroups.com
Hey Michael,

Sorry, I'm not sure what you're meaning by that...I tried to use just
plain java objects and not the ruby helpers for the cypher queries,
but I kept running into problems whenever I used the node(*) in my
query. For some reason, the ExecutionResult doesn't want to be
iterated on...even something simple like "START n=node(*) RETURN n"
throws an error whenever I try and go through the results...

However, this does seem to work for what I'm needing:

"START n = node:Person_exact('*:*') MATCH
n-[r:`Person#created_work`]->c RETURN n.name, count(r) as connections
ORDER BY connections DESC"

This seems to return the results I'm looking for, both in the neo4j
console and in jruby...does this seem reasonable to use the lucene
indexing rather than node(*) or am is this a bad idea?

thx, fitz.

On Wed, Aug 1, 2012 at 9:51 PM, Michael Hunger

Michael Hunger

unread,
Aug 1, 2012, 6:43:46 PM8/1/12
to neo...@googlegroups.com
It should work.

Interesting why you have to traverse all nodes for this query?

What about using an index on a property of your person? like login or lastname and then using the index on that? "login:*"

Michael

Peter Neubauer

unread,
Aug 2, 2012, 3:14:33 AM8/2/12
to neo...@googlegroups.com

Do you have a code example where node(*) doesn't work?

/peter

Send from mobile.

Chris Fitzpatrick

unread,
Aug 2, 2012, 4:38:55 AM8/2/12
to neo...@googlegroups.com

Hi peter,

Sure...so, using a cleaned out graph with only a few test nodes...this works in the console:
 START n = node(*) RETURN n

not pretty, but it spits out all my nodes...

So, in the jruby irb:

jruby-1.6.7.2 :123 > a = Neo4j._query("START n=node(*) RETURN n")
 => #<Neo4j::Core::Cypher::ResultWrapper:0x464826ae @source=#<Java::OrgNeo4jCypherJavacompat::ExecutionResult:0x64983afa>>

jruby-1.6.7.2 :124 > a.first.columns
NativeException: java.lang.ClassCastException: org.jruby.gen.InterfaceImpl1557949290 cannot be cast to org.neo4j.kernel.GraphDatabaseAPI

from org/neo4j/tooling/GlobalGraphOperations.java:39:in `<init>'
from org/neo4j/tooling/GlobalGraphOperations.java:51:in `at'
from org/neo4j/cypher/internal/executionplan/builders/GraphGlobalStartBuilder.scala:45:in `apply'
from org/neo4j/cypher/internal/executionplan/builders/GraphGlobalStartBuilder.scala:45:in `apply'
from org/neo4j/cypher/internal/pipes/StartPipe.scala:38:in `apply'
from org/neo4j/cypher/internal/pipes/StartPipe.scala:37:in `apply'
from scala/collection/TraversableLike.scala:200:in `apply'
from scala/collection/TraversableLike.scala:200:in `apply'
from scala/collection/LinearSeqOptimized.scala:59:in `foreach'
from scala/collection/immutable/List.scala:45:in `foreach'
from scala/collection/TraversableLike.scala:200:in `flatMap'
from scala/collection/immutable/List.scala:45:in `flatMap'
from org/neo4j/cypher/internal/pipes/StartPipe.scala:37:in `createResults'
from org/neo4j/cypher/internal/pipes/ColumnFilterPipe.scala:37:in `createResults'
from org/neo4j/cypher/internal/executionplan/ExecutionPlanImpl.scala:62:in `apply'
from org/neo4j/cypher/internal/executionplan/ExecutionPlanImpl.scala:62:in `apply'
... 2 levels...
from org/neo4j/cypher/PipeExecutionResult.scala:140:in `hasNext'
from scala/collection/Iterator.scala:334:in `hasNext'
from scala/collection/JavaConversions.scala:562:in `hasNext'
from /Users/chrisfitzpatrick/.rvm/rubies/jruby-1.6.7.2/lib/ruby/site_ruby/shared/builtin/java/java.lang.rb:12:in `each'
from /Users/chrisfitzpatrick/.rvm/gems/jruby-1.6.7.2@beacon/gems/neo4j-core-2.0.1-java/lib/neo4j-core/cypher/result_wrapper.rb:32:in `each'
from org/jruby/RubyEnumerable.java:326:in `first'



So, the query runs and returns an ExecutionResult object, but jruby chokes when I try iterate through it. However, I can do all kinds of queries and process the results as long as I don't use a node(*).

Like :

jruby-1.6.7.2 :156 > q= Neo4j._query("START n0=node:Person_fulltext('name:homer') MATCH (n0)-[r:`Person#created_work`]-(c) RETURN n0,count(r)" )
 => #<Neo4j::Core::Cypher::ResultWrapper:0x1ec96f1a @source=<Java::OrgNeo4jCypherJavacompat::ExecutionResult:0x1ec51c5e>>

jruby-1.6.7.2 :161 > q.first[:n0].name
 => "Homer" 

However, I am thinking using the node(*) is probably overkill anyways. Doing this:
 q= Neo4j.query {  query(Person, "'*:*'", :fulltext) -( r =  rel("r:`Person#created_work`") ) - :c; ret n, count(r) }  

(which is DSL for "START n0=node:Person_fulltext('*:*') MATCH (n0)-[r:`Person#created_work`]-(c) RETURN n0,count(r)"  )

is probably better, since it starting with only Person nodes rather than all nodes.
Does that make sense? 

I'm not really sure what to make of the node(*) issue, as it seem to be a jruby interoperability problem.

b,fitz. 

Peter Neubauer

unread,
Aug 2, 2012, 4:40:57 AM8/2/12
to neo...@googlegroups.com, Andreas Ronge
Yes,
you should raise this as an issue in neo4jrb, I guess this needs to be
investigated. Thanks Chris!

Cheers,

/peter neubauer

G: neubauer.peter
S: peter.neubauer
P: +46 704 106975
L: http://www.linkedin.com/in/neubauer
T: @peterneubauer

Wanna learn something new? Come to @graphconnect.


On Thu, Aug 2, 2012 at 10:38 AM, Chris Fitzpatrick

Andreas Ronge

unread,
Aug 2, 2012, 5:49:40 PM8/2/12
to neo...@googlegroups.com
Hi

Very strange indeed since nothing much is executed in the JRuby layer.
Looks like it's a neo4j-core bug or maybe even a JRuby bug ???
Also strange that the cypher layer is trying to cast a Ruby object
into a org.neo4j.kernel.GraphDatabaseAPI interface.
I've also tested with 1.8.M06 (will soon release it) - no change.
You are welcome to add an issue on the neo4j-core github project (or I
do it myself)
Cheers

Andreas Ronge

unread,
Aug 5, 2012, 3:01:11 AM8/5/12
to neo...@googlegroups.com
Hi

I've now fixed it. I simply implemented the deprecated Java interface
GraphDatabaseAPI on one of my internal ruby objects
(Neo4j::Core::Database).
Still a mystery how the Java/Cypher layer gets hold of my
Neo4j::Core::Database instance.

https://github.com/andreasronge/neo4j-core/issues/13

Btw, I'm releasing the neo4j-community 1.8.M06 now which does not work
with neo4j 2.0.x since the 1.8.M05 had some breaking changes.
There will be a neo4jrb 2.1 release soon which will work with the
latest jar files.

Cheers.

Michael Hunger

unread,
Aug 5, 2012, 4:25:49 AM8/5/12
to neo...@googlegroups.com
Andreas,

some of the breaking API changes have been reverted in SNAPSHOT and will be available in the next milestone.
Please check if 2.0.x works against 1.8-SNAP

Michael

Andreas Ronge

unread,
Aug 5, 2012, 4:38:03 AM8/5/12
to neo...@googlegroups.com
Thanks, that's good news. Make life easier for me.
Anyway, I pushed my fixes to neo4j-core (for example, fix for the
expand traversal method now uses a Path object instead of a
Relationship)
I guess I have to revert my fixes too.

Cheers
Reply all
Reply to author
Forward
0 new messages