2
votes

I'm using Neo4j to find Users who are in a 50 km radius and who are available on specific days.

This question is similar to this other question but Indexes have changed since Neo4J 2.0 so the solution does not work.

I use Neo4j 2.2.1, Neo4j-spatial 0.14 and py2neo / py2neo-spatial to interact with the graph.

To add user geometries to the graph I use:

def create_geo_node(graph, node, layer_name, name, latitude, longitude):
  spatial = Spatial(graph)
  layer = spatial.create_layer(layer_name)
  node_id = node._id
  shape = parse_lat_long(latitude, longitude)
  spatial.create_geometry(geometry_name=name, wkt_string=shape.wkt, layer_name="Users", node_id=node_id)

..which creates the spatial nodes as wanted.

I then would like to query the graph by doing:

START user=node:Users('withinDistance:[4.8,45.8,100]')
MATCH period=(start_date:Date)-[:NEXT_DAY*]->(end_date:Date)
    WHERE start_date.date="2014-03-03" AND end_date.date="2014-03-04"
    UNWIND nodes(period) as nodes_in_period
    OPTIONAL MATCH (nodes_in_period)<-[a:AVAILABLE]-(user:User)
    RETURN user.uuid, count(a)/count(nodes(period))

but the query returns:

Index `Users` does not exist 
  • Is seems that the py2neo spatial.create_layer(..) creates the layer but not the Index (but should it? ..as Indexes are now a "Legacy" of Neo4j 1.*)

  • Using py2neo spatial find_within_distance works but since it uses the REST api I cannot make mixed requests which take into account other parameters

  • From what I understand, START is deprecated since Neo4j 2.0 but I am unable to find the correct Cypher query for withinDistance in Neo4j 2.2

Thank you in advance,

Benjamin

2
miss-understanding of the indexes here. possibly bad use of language on the spatial side.... but create_layer does not create a typical Neo index - it creates a graph that it can then use to efficiently carry out spatial-type queries on related application nodes. You should never have to worry about this index.noisyboiler

2 Answers

2
votes

create_layer creates a "spatial" index which is different to Neo's Indexes. It actually creates a graph which models some bounding boxes for you so that you can then carry out spatial queries over your data. You don't need to reference this index directly. Think of it more like a GIS layer.

You can inspect your graph and dig out the Node attributes you need to write your own cypher query.

But you could also use the py2neo spatial API find_within_distance http://py2neo.org/2.0/ext/spatial.html#py2neo.ext.spatial.plugin.Spatial.find_within_distance

Hope this helps.

0
votes

I think that those links can be usefull : * Neo4j Spatial 'WithinDistance' Cypher query returns empty while REST call returns data * https://github.com/neo4j-contrib/spatial/issues/106

But the problem is not that you haven't got any result, but an error on the index ... that's why I'm perplex.

Can you test neo4j spatial directly with some REST query (to create layer & spatial node) to see what happen ?

Otherwise, for your question about cypher start condition, you just have to put this condition into the match one like this :

MATCH 
    user=node:Users('withinDistance:[4.8,45.8,100]'),
    period=(start_date:Date {date:'2014-03-03'})-[:NEXT_DAY*]->(end_date:Date {date:'2014-03-04'})
UNWIND nodes(period) as nodes_in_period
OPTIONAL MATCH (nodes_in_period)<-[a:AVAILABLE]-(user:User)
RETURN user.uuid, count(a)/count(nodes(period))