Neo4j 3.0.0 + SPATIAL in Cypher - neo4j

I've compiled the latest Neo4j Spatial (neo4j-spatial-0.16-neo4j-3.0.0-server-plugin.jar) from source and dropped it into my Neo4j 3.0.0 plugins folder.
The extension is listed in the browser, and I can do POST calls for spatial functionality.
However, I believe I should also be able to use the nifty new CALL feature in Neo4j 3.0.0 to make Cypher calls, like this:
CALL spatial.addPointLayer('cities');
As alluded to by Stefan's update here:
How do I create a spacial index in neo4j using only cypher?
And shown here:
http://jexp.github.io/graphgist/idx?dropbox-14493611%2Fcypher_spatial.adoc
However, I get a "There is no procedure with the name spatial.addPointLayer registered for this database instance." error, and can see the same calls failing in the jexp example as well... I'm not sure if I'm just too early to the party or missing something?

The plugin needs to be in the database-specific Plugin folder and not in the "Neo4j CE 3.0.x/Plugins" folder.

In Neo4j 3.0, for basic operations you don't need the spatial plugin.
There is default support for point and distance. This support assumes you will set lat/lon property keys as latitude and longitude.
You can the use them for calculating distance between two nodes, for example :
MATCH (a:City {name:'London'}), (b:City {name:'Barcelona'})
RETURN distance(point(a), point(b))/1000 as dist
You can find a detailed example in this graphgist :
http://gist.asciidoctor.org/?dropbox-14493611%2Fcypher_spatial.adoc#_spatial_procedures
Secondly, in Neo4j 3.0 appears stored procedures, an official set of procedures is supported by neo4j here :
https://github.com/neo4j-contrib/neo4j-apoc-procedures
Which provides some more spatial features.

Related

What is neo4j closest feature to sql stored functions?

I'm new to neo4j and graph databases in general.
Given a complex Cypher query, that I don't want to store inside the application (or several applications), but keep centralized, what options are left to me?
In a SQL database I would use a stored function. Are UDF function the way to go in neo4j?
From the docs it seems to me that they're more a way to extend the database functionality by being able to access the graph internals, but I've just started studying them.
Take a look at the custom functions and procedures available in the apoc library.
https://neo4j.com/docs/labs/apoc/current/cypher-execution/cypher-based-procedures-functions/
CALL apoc.custom.asProcedure('answer','RETURN 42 as answer')
CALL custom.answer() YIELD row RETURN row.answer

Embedded automatic full text indexing completely removed from Neo4j as of 3.0.0?

I'm moving from Neo4j 2.2.* to (still prerelease) 3.0.0 and all of a sudden it seems that configuration parameters
node_auto_indexing=true
relationship_auto_indexing=true
node_keys_indexable=some_node_property
relationship_keys_indexable=some_rel_property
had gone and are not available any more. This is sad because I need full-text indexing (namely, fuzzy search queries and range searches), I was happily using it since 2.0.0 and had a naive hope that new Lucene 5.5 will make my life better with 3.0.0.
Is this functionality completely removed? START clause is still here in Cypher, neo4j-shell still has command which allows manipulating "legacy" FT indices so my question is:
how do I populate my FT index without using Java or another external programming language?
case 1: I import some bunch of "static" data into the graph which
will rarely be updated (consider dictionary) and need to arrange FTS
on those once, and manually perform complete reindex on occasional updates of the dataset;
case 2: nodes and relationships with specific properties
automagically get indexed upon creation or upon assignment of a new value to the property with specific name, near-realtime, as it used to be before.
New schema indexes are cool in 3.0.0 and range searches are implemented, but a) they work only on properties of nodes, no relationships, b) they don't allow full-text, fuzzy queries, and AFAIK regular expression matching does not use index.
Thanks for your suggestions!
WBR, Andrii
Andrii,
only the default config parameters have been removed not the functionality.
What is the actual use-case you are using the FTS indexes (on rels) for?
In 3.0 you can still use the start-clause but using stored procedures you can add nodes and relationship explicitly to indexes. And you can use similar procedures to query your indexes even more efficiently, e.g. by passing in start and end-nodes.
See (WIP): https://github.com/jexp/neo4j-apoc-procedures#manual-indexes

Updating neo4j from 2.1.1 to 2.1.6 losing spatial data

I'm trying to upgrade my database neo4j from 2.1.1 to 2.1.6.
It has spatial indexes inside and I configured the neo4j.properties to set
allow_store_upgrade=true
But even with that configuration, when I run neo4j, my database's weight goes from 88Mb to 14Mb. All the nodes are there, but when I run a spatial query I get
Neo.DatabaseError.Statement.ExecutionFailure
Is there anything I can do about it?
EDIT
Apparently the lose of weight is because neo4j wipes out all the log files, not losing data. Is seems to be a spatial error in v2.1.6 with my current DB from v2.1.1 (Using spatial plugin v2.1.2)
If I replace neo4j-spatial-0.13-neo4j-2.1.6.jar with neo4j-spatial-0.13-neo4j-2.1.2.jar it works, which is a bit weird because it looks like v2.1.6 cannot read the information stored by v2.1.2
EDIT 2
The query I'm running is:
START n=node:LocationIndex('withinDistance:[51.0,-0.12,10.0]') RETURN n;
where LocationIndex is my spatial index.
The DB structure contains nodes with wkt, lon and lat like this:
wkt: POINT(-0.142309 51.538400)
lon: -0.122309
lat: 51.5384
When I add the old plugin it returns all the nodes, with the old one it returns the error above.
What can be the error and how can I upgrade my spatial information?

Querying in Gremlin using multiple indices

I am trying to optimize requests in Gremlin on a Neo4J graph.
Here is the short version of the basic request I am using:
g.idx("myIndex")[[myId:5]].outE("HAS_PRODUCT").filter{it.shop_id:5}.inV
So I looked into indexation and got to create an index on "HAS_PRODUCT"-typed edges with key 'shop_id'.
Using the same request, I don't see a big difference.
My questions are:
Is my new index used when I query with: filter{it.shop_id:5}
If not, how can I use this new index in my request?
More generally, if idx( is the graph method to use an index, is there a pipe method for that?
Thanks!
The short answer is that Gremlin won't make use of the secondary index when using Neo4j, but please consider reading the longer answer below in relation to TinkerPop, Gremlin and its philosophy.
The longer answer is....Indices are not being used for your shop_id. When you call outE you are effectively iterating all the edges to find those with shop_id == 5. To make use of indices in Gremlin you should use a vertex query. So, rewriting your code a bit (to also use key indices) would be like:
g.V('myIndex',5).outE('HAS_PRODUCT').has('shop_id',5).inV
With Blueprints implementations that support vertex-centric indices, the use of has will utilize that index automatically. Unfortunately, Neo4j is not one of those databases yet. Blueprints implementations that do implement it, include Titan (see Vertex-centric indices) and OrientDB (as part of the yet unreleased Blueprints 2.4.0...I believe they will have a partial implementation in that release) in that case.

Determine security in an ACL using Neo4j and Gremlin

I'm researching Neo4j to compare it's performance for implementing an access control list. It seems like this is a great fit.
Here's an article from a few years ago describing this exact use case.
http://blog.neo4j.org/2010/02/access-control-lists-graph-database-way.html.
The has_access method though is written in ruby. I would think that using gremlin to process the query on the server would be more efficient for large graphs. How would I determine if a user has access to a node using Gremlin?
Thanks!
It turns out that for this problem, access to a folder can be determined by parsing the shortest paths between the user and the user and the folder.
Here is a cypher query that returns the shortest paths between two nodes, where the user is at node 157 and the folder is at node 160.
START u=node(157),f=node(160)
MATCH p=allShortestPaths(u-[*]->f)
RETURN p

Resources