Jett Kam
Jett Kam

Reputation: 77

Neo4jrb - Cypher query

I have a database like in this question:

Neo4j - Finding the Shortest Path between two nodes based on relationship property

CREATE (some_point_1:Point {title:'Some Point 1'})
CREATE (some_point_2:Point {title:'Some Point 2'})
CREATE (some_point_3:Point {title:'Some Point 3'})
CREATE (some_point_4:Point {title:'Some Point 4'})
CREATE (some_point_5:Point {title:'Some Point 5'})
CREATE (some_point_6:Point {title:'Some Point 6'})

CREATE (some_point_1)-[:distance {value:100}]->(some_point_2)
CREATE (some_point_2)-[:distance {value:150}]->(some_point_4)
CREATE (some_point_1)-[:distance {value:200}]->(some_point_3)
CREATE (some_point_3)-[:distance {value:300}]->(some_point_4)
CREATE (some_point_2)-[:distance {value:500}]->(some_point_5)
CREATE (some_point_4)-[:distance {value:300}]->(some_point_5)
CREATE (some_point_5)-[:distance {value:300}]->(some_point_6)
CREATE (some_point_6)-[:distance {value:300}]->(some_point_1)

Now I'm trying to execute a query like this: (from a Rails app)

MATCH (start:Point {title: 'Some Point 1'}), (end:Point {title: 'Some Point 5'})
MATCH p=(start)-[:distance*]->(end)
WITH p,reduce(s = 0, r IN rels(p) | s + r.value) AS dist
RETURN p, dist ORDER BY dist DESC

I'm trying to do a similar query with the active model wrapper, but it's not working :(

Is there a way to execute a pure Cypher query from neo4jrb or neo4j-core?

Upvotes: 1

Views: 337

Answers (3)

Brian Underwood
Brian Underwood

Reputation: 10856

Guillermo is absolutely right, but I thought I would give a stab at some code:

Point.where(title: 'Some Point 1').connected(:end, :rels, rel_length: :any).where(title: 'Some Point 5')
   .query.with(:p, dist: 'reduce(s = 0, r IN :rels | s + r.value)')
   .return(:p, :dist)
   .order(disc: :desc)

That will give you an Enumerable which you can iterate over or call to_a on. Or you could return a two dimensional array directly:

   .order(disc: :desc)
   .pluck(:p, :dist)

This assumes an ActiveNode model as Guillermo said. Something like;

class Point
  include Neo4j::ActiveNode
  property :title

  has_many :out, :connected, type: :distance, model_class: :Point
end

The name of the association may or may not be what you want, I just guessed.

Upvotes: 0

Brian Underwood
Brian Underwood

Reputation: 10856

MATCH (start:Point {title: 'Some Point 1'}), (end:Point {title: 'Some Point 5'}) MATCH p=(start)-[:distance*]->(end) WITH p,reduce(s = 0, r IN rels(p) | s + r.value) AS dist RETURN p, dist ORDER BY dist DESC

Guillermo is absolutely right, but I thought I would give a stab at some code:

Point.where(title: 'Some Point 1').connected(:end, :rels, rel_length: :any).where(title: 'Some Point 5')
   .query.with(:p, dist: 'reduce(s = 0, r IN :rels | s + r.value)')
   .return(:p, :dist)
   .order(disc: :desc)

That will give you an Enumerable which you can iterate over or call to_a on. Or you could return a two dimensional array directly:

   .order(disc: :desc)
   .pluck(:p, :dist)

This assumes an ActiveNode model as Guillermo said. Something like;

class Point
  include Neo4j::ActiveNode
  property :title

  has_many :out, :connected, type: :distance, model_class: :Point
end

The name of the association may or may not be what you want, I just guessed.

Upvotes: 0

Guille
Guille

Reputation: 755

Yes, you can easily do Cypher directly if you want via the neo4j-core gem (which you need anyways when using the neo4j gem).

For example: n = Neo4j::Session.query("MATCH (n) RETURN n").first (assuming you have configured you application to communicate with the Neo4j server).

If you are using the neo4j gem you need to have the corresponding ActiveNode (and possibly ActiveRel) models in your application so that you can do your queries. This gem is pretty much a nice wrapper of the standard ActiveModel for Neo4j :)

You have more information on how to: https://github.com/neo4jrb/neo4j-core/wiki/Queries You can also move from a QueryProxy chain to a Neo4j::Core::Query. See https://github.com/neo4jrb/neo4j/wiki/Search-and-Match#detailed-querying

Upvotes: 1

Related Questions