spatial icon indicating copy to clipboard operation
spatial copied to clipboard

findGeometriesWithinDistance: how to use it with limit and orderBy in NodeJs

Open elgreatly opened this issue 9 years ago • 12 comments

i used SpatialPlugin with NodeJS

when i used cypher query

node=node:geom('withinDistance:[48.2,16.3,100.0]') return node

it returned error "Index 'geom' does not exists"

but when i used this

{"layer":"geom","pointX":16.3,"pointY":48.2,"distanceInKm":100.0}' --header "Content-Type:application/json" http://localhost:7474/db/data/ext/SpatialPlugin/graphdb/findGeometriesWithinDistance

it works but i want to add order by and limit for this query and in this request i can't anyone can help me? thanks a lot

elgreatly avatar Jun 03 '16 17:06 elgreatly

That's a thing I had to figure out too: It's basically two different addressing schemes, the first method works on a Neo4j index while the second one uses a Spatial layer. However, I couldn't find a simple way to create an index out of a layer either. (Fortunately I got around it by working plainly on the Java API.) So the question basically is: How to build an index from a layer?

ehx-v1 avatar Jun 06 '16 11:06 ehx-v1

i'm working on it with nodejs. i think index doesn't work from rest api then i work on it using Spatial layer but i can't order by and limit on this query. i want to get nodes within distance with limit and order by

elgreatly avatar Jun 06 '16 12:06 elgreatly

That's kind of the trouble about it: For using LIMIT and ORDER BY, you need an index. So you need to somehow create it out of a layer. The only thing I can think of is a manual CREATE INDEX, but if you use Node.js you'll probably want to put it into code. Let's wait if someone has a better idea.

ehx-v1 avatar Jun 06 '16 12:06 ehx-v1

Thank you for your help i appreciate that CREATE INDEX i can do that but what do you mean? i created index for property that what you mean how can CREATE INDEX to match geom in query i'm already doing that

:POST /db/data/index/node {"name":"geom", "config": 
  {"provider":"spatial", "geometry_type":"point", "lat":"lat", "lon":"lon"}
}

elgreatly avatar Jun 06 '16 12:06 elgreatly

All the nodes must be on the layer AND on the index. That's what I mean by, it might be too much trouble doing that via code. Putting each node on the index manually doesn't seem practicable...

However, I've already seen @craigtaverner putting up unexpected solutions for problems like this one. We should see whether he has an idea on how to tackle this.

ehx-v1 avatar Jun 06 '16 12:06 ehx-v1

A quick answer - following on from what @ehx-v1 said, there are two somewhat incompatible ways of interacting with the spatial index remotely.

The REST API provided by the plugin uses new REST endpoints like 'add*Layer' (see http://neo4j-contrib.github.io/spatial/#rest-api-create-a-pointlayer) and then 'addNodeToLayer' to add your node to the layer. In this case you must use the REST endpoints defined for finding nodes too, like http://neo4j-contrib.github.io/spatial/#rest-api-find-geometries-within--distance.

The alternative is to make the layer look like a legacy index to Neo4j, and use Cypher to query. This stores the data slightly differently as in then mostly incompatible. Some users have found ways to get the same nodes to be accessible in both ways (via REST or by Cypher START clause), but this is messy. The documentation for creating the legacy index can be found here: http://neo4j-contrib.github.io/spatial/#rest-api-create-a-spatial-index. Then you need to separately add your node to the index using the legacy index documentation: http://neo4j.com/docs/2.3.4/rest-api-indexes.html#rest-api-add-node-to-index. And query using the Cypher syntax described here: http://neo4j-contrib.github.io/spatial/#rest-api-find-geometries-within--distance-using-cypher.

I've not played with this much myself (specifically the legacy index approach), as my involvement with this project was focused on using it from Java in embedded environments. But My suspicion is that you have missed the 'add node to index' step for legacy indexes.

I also think you should pick one approach (REST versus Legacy Index) and stick to the one. Mixing them up causes problems. For the new release for Neo4j 3.0 we are actually removing the legacy index support for spatial because we think the new Cypher procedures are much easier to maintain, provide richer spatial experience from Cypher and don't have this awkward disconnect with the REST API. If you want to move to Neo4j 3.0, you can try this already, as there is a preliminary release available. We hope to make a new one within the next week or two that is a little more refined.

craigtaverner avatar Jun 06 '16 15:06 craigtaverner

But... there are ways known to combine these? Complicated but clean? How? Where? That would truly interest me, how someone made that. That will probably be some insanely innovative approach I'd really like to see.

ehx-v1 avatar Jun 07 '16 12:06 ehx-v1

There have been discussions on this in the past, ways to combine the two. I did a quick search and found the following two:

  • http://stackoverflow.com/questions/25017295/neo4j-spatial-return-only-one-node
  • http://stackoverflow.com/questions/17966722/neo4j-spatial-withindistance-cypher-query-returns-empty-while-rest-call-return

craigtaverner avatar Jun 07 '16 19:06 craigtaverner

After looking at this concept (I got lost on Puzzling SE afterwards lol) I'd say it isn't even that complicated. Just like adding to layer, except for parsing the response for the node IDs (ok this might be complicated) and adding the ID as property to each node. One could also MERGE the property on the nodes, which would be a single Cypher statement but you'd have to go over the whole graph so it could run quite slow...

Gesendet von meinem LG Mobile

Am 07.06.2016 21:50 schrieb Craig Taverner [email protected]:

There have need discussions on this in the past, ways to combine the two. I did a quick search and found the following two:

http://stackoverflow.com/questions/25017295/neo4j-spatial-return-only-one-nodehttp://stackoverflow.com/questions/17966722/neo4j-spatial-withindistance-cypher-query-returns-empty-while-rest-call-return

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

ehx-v1 avatar Jun 08 '16 16:06 ehx-v1

I would also like to point out that this whole issue of REST versus Cypher-legacy-index kind-of goes away in the 3.0 release which supports procedures in Cypher. We are making releases of Spatial where you can access functions like the REST API from within Cypher. And therefor we also are entirely removing the legacy-index support. It only existed to give Cypher users some way to access spatial, but the inconsistencies were a lot of trouble. With the procedures, Cypher access is much more compatible with REST (and Java API) access.

If you are amenable to upgrading to neo4j 3.0, this is the best option for you, I believe.

Then you can use Cypher's own ORDER BY and LIMIT.

craigtaverner avatar Jun 16 '16 09:06 craigtaverner

If you wonder why I deleted so many comments of mine, it's been bull. I first thought the workaround hadn't applied, then it turned out I just didn't update my Maven dependencies for a while, so the encoding property was still "wkt" while I thought it would already be "geometry". Now that I fixed my dependencies, all my JUnit tests are green ;-)

ehx-v1 avatar Jun 22 '16 13:06 ehx-v1

Also, what should work easily for making the node accessible via both end points: After each import (which will most probably be always to a different layer), you run through all imported nodes and add the self-referential ID. Another easy way, but some import methods don't support this: Whenever you add a node, you immediately add the self-referential ID property. (That's how I'm doing it, by the way. It's needed because I add the nodes to the layer as geometries.)

ehx-v1 avatar Jul 28 '16 06:07 ehx-v1