Hot questions for Using Neo4j in graph

Question:

I updated my Graph DB from Neo4J 2.0.4 to Neo4J 3.3.3 and when I run it with my app it's now using twice more memory (java process on my Mac) than before. (I run Java 1.8 on my Mac)

When I launch Neo4J 2 it uses about 250Mb for the same tasks and queries. But Neo4J 3 uses about 500Mb.

I thought the updates were supposed to be more efficient?

What would be a possible way to decrease the memory use?


Answer:

Neo4j is based on the JVM, its memory cnsumption depends of the size of the Heap.

If you have not configure its size, Neo4j has a heursitic to calcul it, and by the time this heuristic has changed.

In Neo4j 3.X, there are 3 memory spaces :

JVM heap

Heap is used for storing all transaction's data, locks on nodes and relationships, and also to cache query's execution plan.

You can configure its size in conf/neo4j.conf :

# Java Heap Size: by default the Java heap size is dynamically
# calculated based on available system resources.
# Uncomment these lines to set specific initial and maximum
# heap size.
dbms.memory.heap.initial_size=512m
dbms.memory.heap.max_size=512m
Page cache

A database does a lot of IO on disk. To be fast, it needs to put in RAM your data. Neo4j 3.X does it with the pagecache mechanism, that put in RAM some parts of its binary data files. So your most used data are in RAM.

This can be configure in conf/neo4j.conf :

# The default page cache memory assumes the machine is dedicated to running
 # Neo4j, and is heuristically set to 50% of RAM minus the max Java heap size.
dbms.memory.pagecache.size=10g
Indexes

Indexes are used to find rapidly nodes for your queries, but if those indexes are not in RAM, they will be slow.

There is no way to configure this memory siz in Neo4j, but with a rule of three its easy to calculate (Server RAM = Heap + pagecache + indexes + some free memory for the OS).

You can calculate the size of your indexes with this command :

$> du -sh data/databases/graph.db/indexes
Conclusion

Since Neo4j 2, there are a lot of improvements (functionnalities, performances), so yes it's more efficient.

More efficient about the finger print on RAM, I don't know, I have never done such test, but RAM is cheap now days.

The only thing I can tell you is that you should need a lesser heap, the data cache are off heap now. In 2.X, Neo4j kept a graph in memory for fast access.

But Neo4j is highly configurable, so if you have a tiny server and want to fine tune the memory consumption, you have to set heap and pagecache size.

Question:

Im having error in executing Cypher query in java (embedded mode) This is my code:

    import org.neo4j.cypher.internal.ExecutionEngine;
    import org.neo4j.cypher.internal.ExecutionResult;
    import org.neo4j.graphdb.GraphDatabaseService;
    import org.neo4j.graphdb.factory.GraphDatabaseFactory;
    public class test {
    public static void main(String[] args) {
    GraphDatabaseFactory graphdbFactory = new GraphDatabaseFactory();
    GraphDatabaseService graphdb = new graphdbFactory.newEmbeddedDatabase("C:/Users/dell/Documents/Neo4j");    
    ExecutionEngine execEngine = new ExecutionEngine(graphDb);
    ExecutionResult execResult = execEngine.execute
               ("MATCH (java:JAVA) RETURN java");
    String results = execResult.dumpToString();
    System.out.println(results);
}

}

Im getting error at the line : GraphDatabaseService graphdb = new graphdbFactory.newEmbeddedDatabase("C:/Users/dell/Documents/Neo4j"); error: the method new embedded database (file) in the type graph database factory is not applicable for the arguments (string)

please help


Answer:

GraphDatabaseFactory.newEmbeddedDatabase() expects a File and not a String, see http://neo4j.com/docs/java-reference/current/javadocs/org/neo4j/graphdb/factory/GraphDatabaseFactory.html#newEmbeddedDatabase-java.io.File-

Also there's no need to use ExecutionEngine. Just do a graphDb.execute(<cypherString>). Note this applies to Neo4j >= 2.3.

Question:

I'm integrating my system with neo4j and it would be interesting to me to create nodes using the Cypher query language, therefore, as a test, I'm trying to do something like this:

String path = "test.graphdb";

AbstractDatabase db = new Neo4jDatabase(path, true, false);

db.makeQuery("CREATE (n:Dog {name:'Sofia'})");
db.makeQuery("CREATE (n:Dog {name:'Laika'})");     db.makeQuery("CREATE (n:Dog {name:'Gaia'})");

Result result = db.makeQuery("MATCH (n:Dog) RETURN n");

boolean hasNext = result.hasNext();

System.out.println(hasNext);

Where inside the Neo4jDatabase class I have this makeQuery method which goes like this:

public Result makeQuery(String string)
{
    try(Transaction ignored = this.db.beginTx();
        Result result = this.db.execute(string) )
    {
        return result;
    }

}

Unfortunately, it returns false, as if the nodes had not been created! What is wrong?


Answer:

You say it yourself, you ignore the transaction :)

You should call tx.success() in your transaction block, after you successfully iterated over the result.

Don't hand out the result when you already closed the transaction, the data in it will not be accessible outside of a tx.

For these simple statements you can also leave the tx-handling to cypher, no need to start manual transactions.

But you have to iterate over or result.close() your results to finish the Cypher operation.

Question:

I have just updated from Spring Data Neo4j 4.1.3 to 4.2.7

But, I have not been able to get my project to start running again after changing the maven dependency.

I have fixed many issues as described in this tutorial: https://graphaware.com/neo4j/2016/09/30/upgrading-to-sdn-42.html But I cannot figure out why this issue has emerged.

In my service > GenericService.java > createOrUpdate

...
@Override
public T createOrUpdate(T entity) {
    getRepository().save(entity, DEPTH_ENTITY_NEXT); //ERROR LINE
    if (entity instanceof Entity)
        return find(((Entity) entity).getId());
    else if (entity instanceof GraphType)
        return find(((GraphType) entity).getId());
    else 
        return find(((DataType) entity).getId());
}
...

The getRepository line now gives the following error:

The method save(T, int) is ambiguous for the type 
    GraphRepository<T>

simply saving the graph repo seems to be erroring.

UPDATE

If I just try to Maven build the project even though eclipse shows the error. It prints this error:

Caused by: java.io.FileNotFoundException: class path resource [org/springframework/data/neo4j/config/Neo4jConfiguration.class] cannot be opened because it does not exist

Answer:

You probably have a problem in your dependency management. Please see the templates for examples on how to configure your project.

Also note that GraphRepository is deprecated and replaced by Neo4jRepository<T, ID>.

Question:

I am using Neo4j Graph Database for my java project. I am creating .db folder by java program by inputting one .xls file. I am able to update the graph database only when it is shutdown. I am using Neo4j 3.0.7 version. Is it possible to update the graph database while it is in running state?


Answer:

What you have to do is to use the same jar version and Neo4j installed in your system which you are using to open the db folder. Make sure to use the same version of jar and Neo4j installed.

Question:

I'd like to order returned data by relevance in Neo4j.

For my purpose, relevance can be simplified to "Index of the word I'm searching for", where the lower index the higher relevance.

Example

I have these three nodes:

node : {
    Label: PROD
    properties : {
        name: "Bearing replacement Skateboard"
    }
}

node : {
    Label: PROD
    properties : {
        name: "Skateboard"
    }
}

node : {
    Label: PROD
    properties : {
        name: "L7 Skateboard"
    }
}

I want them to be returned with this order:

node : {
    Label: PROD
    properties : {
        name: "Skateboard" // name.indexOf("Skateboard") = 0
    }
}

node : {
    Label: PROD
    properties : {
        name: "L7 Skateboard"  // name.indexOf("Skateboard") = 3
    }
}

node : {
    Label: PROD
    properties : {
        name: "Bearing replacement Skateboard"  // name.indexOf("Skateboard") = 19
    }
}

What I have so far:

String query = "MATCH (n:PROD) where LOWER(n.name) CONTAINS LOWER({textToSearch}) RETURN n ORDER BY LOWER(n.name) ASC LIMIT 15";

String textToSearch = "Skateboard";

Map<String, Object> queryParams = new HashMap<>();
queryParams.put("textToSearch", textToSearch);
try (
    Transaction ignored = database.beginTx();
    Result resultSet = database.execute(query, queryParams)
) {
    Iterator<Node> results = resultSet.columnAs("n");
    while (results.hasNext()) {
        Node node = results.next();
        /* data processing here */
    }
}

This just orders results by name ascendant. Is there a way to tell neo4j to sort based on n.name.indexOf({textToFind})?


Answer:

How about doing something like this in Cypher

MATCH (n:PROD) 
WHERE n.name_lc CONTAINS toLower({textToSearch})
WITH n, SPLIT(n.name_lc, toLower({textToSearch})) as parts
RETURN n.name, SIZE(parts[0]) AS leading
ORDER BY leading

To make effective use of the above...

Create an index on a lowercase version of the property

CREATE INDEX ON :PROD(name_lc)

Copy the regular name to a lowercase version

MATCH (n:PPOD)
SET n.name_lc = toLower(n.name)

Question:

As a part of graph decomposition, I split a graph to multiple ones. In order to use them in the next procedures, I want to store splitted graphs in a data structure. How can I store these multiple graphs by a data structure in a memory rather than using disk path for that? If I use newEmbeddedDatabase for that, I should provide a path which is not my requirement.


Answer:

You have two main options to do this.

Option 1

You can use an ImpermanentGraphDatabase as seen in this link where unit testing with neo4j is discussed. Note that this actually does still write temporary files, you just don't need to know/care where they are stored.

Option 2

The second option is to use linux to set up something like ramfs. The idea here is that you're actually creating something which looks like a disk, but it's actually all in memory and so transient/not saved to a hard disk. This option lets you treat your in-memory graph databases just like any other (just another directory on disk).

Neo4j doesn't have an option to do things purely in memory with no persistence to disk, so either of these options lets you do what you want, without having to really think about the disk persistence bits.

Question:

I have two instances of two different database engines (Neo4j and Ontotext GraphDB) and I want to create common interface in GraphQL for these databases.

I want to use Java to create endpoint with GraphQL.

Should I use graphql-java library or do you recommend something else to merging usage of different database engines?

I looking for most flexible solution for this type of problem.


Answer:

GraphQL is designed to be a thin layer above your service layer. It is completely independent of the data storage you are using.

You ask to merge the access to your databases. This is actually a task for your service layer (which is simple java code. Could be backed by Spring for example). Your API layer will then consume your services. GraphQL can be your API layer or part of it.

You should consider either using REST or GraphQL. But having two different databases is not a deciding factor, as this is not the concern for either. You will be fine with both of them. Read this: GraphQL vs REST

If you decide to use GraphQL and Java. graphql-java is your only choice (and it is a good one).

Question:

I have one node in neo4j whose structure looks like:

{
            "nodeId": 32,
            "id": "0290cf88-3345-4c30-8e5f-7ce0cb3f0b6b",
            "type": "User",
            "name": "Mahendra",
            "index": 0,
            "data": "This is sample user",
            "description": null,
            "contentBlocks": [],
            "icon": null,
            "createdOn": null,
            "modifiedOn": null,
            "properties": {
                "displayName": "Mahendra",
                "lastName": "Kawde"
            },
            "tags": [
                "tag1",
                "tag2"
            ],
            "categories": null
        }

Now I want to get all nodes by passing tags as a parameter to my cypher query. I am using below query:

MATCH (node) WHERE node.tags = ['tag1','tag2'] RETURN node

This returns me all nodes with given tags. But if I use below query

MATCH (node) WHERE node.tags = ['tag1'] RETURN node

it does not return me any node.

Also if I change the order lets say ['tag2','tag1'] it does not returns me any node.

Below is my controller method:

@RequestMapping(value = "/getByTag",method = RequestMethod.GET, consumes=MediaType.APPLICATION_JSON, produces=MediaType.APPLICATION_JSON)    
    public Result<Node> getByTag(@RequestParam(value="tags") List<String> tags) throws EntityNotFoundException {
        return nodeService.getByTag(tags);
    }

Service method:

public Result<Node> getByTag(List<String> tags) {

        HashMap params = new HashMap();
        params.put("type",tags);

        String query = "MATCH (node) WHERE node.tags = "+ tags +" RETURN node";

        Result<Node> nodes = neo4jTemplate.query(query, params).to(Node.class);
        return nodes;   
    }

Can you give me a way to use collection, more precisely List<String> in cypher query ?

Please help


Answer:

How about

MATCH (node) 
WHERE ALL (x IN ['tag1','tag2'] WHERE x in node.tags)
RETURN node

See http://neo4j.com/docs/2.2.2/query-predicates.html

Question:

CONTEXT:

I am working on a java spring web application backed by a Neo4j database. I have an object "Student" that has taken a number of "Modules" and "Courses". The relationship is connected via "rich relationship" nodes "RR_TakenModule" and "RR_TakenCourse" that specify a grade property.

public class Student extends DomainObject {
    String fullName;
    Gender gender;
    Collection<RR_TakenModule> modulesTaken;
    Collection<RR_TakenCourse> coursesTaken;
    DateTime yearStarted;

that way I could ask for a Student that got 74% in a Module

PROBLEM:

I cannot return a "deep" object, from the GraphRepository set up. Ie I cannot return a Student with populated "modulesTaken" and "coursesTaken" properties. I've seen several approaches online such as trying the cypher query :

MATCH (student:Student) -[:MODULES_TAKEN]-> (rr:RR_TakenModule) -[:MODULE]-> (m:Module) RETURN student, COLLECT(rr) as modulesTaken

Which is claimed to map the RR_TakenModules into the object dynamically via the property name. It does not do this for me and returns a "Error mapping GraphModel to instance of com.domain.Actors.Student" error code. Although note that it does properly group when running the cypher query in the localhost:7474 interface. Clearly mapping is the issue.

Currently I have adopted the template and Map approach. Using Neo4jOperations and the Result object. This works, however means that I have to write out iterators that go through and assign values based on the key/value pairs in the result object. This leads to high maintenance and a larger chance of errors.

Looking around their used to be options such as @Fetch, and specifying depth in Neo4jTemplate queries, however non of these methods seem to be present in my version (most appear to be depreciated)

QUESTION :

Is there a way to map sub-objects (ie "collection prop" and "set prop") of a Neo4j entity object via Graph Repositories. I realise there are predefined methods such as "findOne" that have a depth parameter, but I want to apply a similar implementation to my custom queries.

Alternatively, is there a solution for dynamically mapping a Neo4jOperations Result object to a java object without defining some custom json parser

VERSIONS :

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.1.RELEASE</version>
</parent>

<properties>
    <java.version>1.8</java.version>
    <spring-data-neo4j.version>4.0.0.RELEASE</spring-data-neo4j.version>
    <spring-data-releasetrain.version>Gosling-RELEASE</spring-data-releasetrain.version>
</properties>

Answer:

Spring Data Neo4j (SDN) does not populate the referenced (by relationship) nodes in the returned node. It will, however populate the fullName and gender properties (assuming here that Gender is an Enum such that a string can be easily mapped).

In your query above you return a Student node and a collection of RR_TakenModule, but Spring does not know how to map this since there's no class that comprises these two results. You need to define an explicit result for this case. I suggest the following:

@NodeEntity(label = "Student")
public class Student extends DomainObject {
    @Property(name = "studentId")
    private String studentId; //you want to have this
    @Property(name = "fullName")
    private String fullName;
    @Property(name = "gender")
    private Gender gender; //assuming its an Enum
    @Relationship(type = "MODULES_TAKEN") // Relationship.OUTGOING is default
    private Set<RR_TakenModule) modulesTaken;
}

Then define a repository

public interface StudentRepository extends GraphRepository<Student> {

    @Query("MATCH (s:Student {studentId:{studentId}})-[:MODULES_TAKEN]->(m:RR_TakenModule) RETURN s AS student, collect(DISTINCT m) AS modulesTaken")
    public StudentWithModulesTakenResult getByUserIdWithModulesTaken(@Param("studentId") String studentId)
}

and the respective result

@QueryResult
public class StudentWithModulesTakenResult {
    private Student student;
    private Set<RR_TakenModule> modulesTaken;
    //only getters, no setters
}

Question:

I am trying to start a new Java project in Neo4J, and going through some tutorials and examples I have seen two way to access Neo4j from Java. The GraphDatabaseServer class and the Bolt driver classes.

As I understand, the GraphDatabaseServer is prefered when you are deploying your application inside the Neo4j DB because it can directly access the underlying DB while the other can make it easy to access an external DB server. Is this correct? Are there any other differences, prefered use cases for one or the other?


Answer:

The two ways of accessing Neo4j via Java you refer to are embedded mode (Neo4j runs in the same JVM as your application), and remote server.

GraphDatabaseService is what gives you access to the embedded Neo4j instance and this is not available to you if your Neo4j instance runs in server mode. Plus, you cannot use this in a non-jvm language.

Bolt on the other hand, is a binary protocol and the preferred way of accessing a remote Neo4j server (instead of the earlier Http based one). Neo4j provides Bolt drivers in various languages. (http://neo4j.com/docs/developer-manual/current/drivers/)

Question:

I am using Neo4j (edit: 2.1.2) from Java and graph.db folder grows huge (more than I can afford to store) while continuously writing data. I have reached more than 40 GB.

I've noticed that if I copy elsewhere the graph.db directory without messages.log and without all nioneo_logial.log.* files, the database is still consistent, I can still read it. Thus, I can rich affordable disk storage for the data (tens/hundreds of MB).

One solution is to regularly stop feeding the graph.db, delete all *.log* files and then restart the application. This is not an acceptable solution! :)

So, is there any way of writing in graph.db without generating all these log files?

Note: I am writing to neo4j while into a transaction

final Transaction tx = db.beginTx();

where db is a GraphDatabaseService object.

Thank you, Costin


Answer:

There is a config open keep_logical_logs which you can set to false to prevent the nioneo_logical.log.* files.

Providing a custom-logback.xml on your classpath with more rigid settings than the one shipping with the .tar.gz distributions can reduce the amount of lines written to messages.log.

Question:

I have to implement a Neo4j Server Plugin that reacts to changes to the Database and get's information about those changes. I need to get all the Data that has been added, changed and deleted in a transaction. I use a TransactionEventHandler registed to the database. For performance reasons i have to use the afterCommit callback that is called after the changes to the database have been made. This way the transaction will not be held back by the plugin.

Now inside this callback i do something similiar to this:

public void afterCommit(TransactionData data, Void arg1) {
    for(Node n:data.createdNodes()) {
        String firstkey = n.getPropertyKeys().iterator().next();
    }
}

But the getPropertyKeys throws an Exception because the transaction has already been commited. I don't understand why this is a problem, i don't want to change anything to the transaction, i just want properties the node has that has been changed. Is there some way to work around this? What is the reason for the Exception?

The Exception:

java.lang.IllegalStateException: This transaction has already been completed.
    at org.neo4j.kernel.impl.api.KernelTransactionImplementation.assertTransactionOpen(KernelTransactionImplementation.java:376)
    at org.neo4j.kernel.impl.api.KernelTransactionImplementation.acquireStatement(KernelTransactionImplementation.java:261)
    at org.neo4j.kernel.impl.api.KernelTransactionImplementation.acquireStatement(KernelTransactionImplementation.java:80)
    at org.neo4j.kernel.impl.core.ThreadToStatementContextBridge.instance(ThreadToStatementContextBridge.java:64)
    at org.neo4j.kernel.InternalAbstractGraphDatabase$8.statement(InternalAbstractGraphDatabase.java:785)
    at org.neo4j.kernel.impl.core.NodeProxy.getPropertyKeys(NodeProxy.java:358)
    at de.example.neo4jVersionControl.ChangeEventListener.afterCommit(ChangeEventListener.java:41)

Answer:

In afterCommit the transaction has already been committed (hence the name). To access properties from a node you need a transactional context - remember that every operations (even readonly) require this.

The recommended way for implementations of TransactionEventHandlers is to rely on TransactionData only. TransactionData.assignedNodeProperties() will return the properties of the newly created nodes as well.

Question:

I'm planning to write a Java application wich relies on a small (Around 3000 nodes) graph to represent its structure. The data should be loaded from a custom file at startup to create an in-memory graph database. I've looked into Neo4j but saw that you can't make it run directly as in-memory. Googling around a bit I found Google JIMFS (Java in-memory file system) may suit my needs.

  • Does anyone have experience with getting Neo4j to work on a JIMFS FileSystem?
  • Are there more suited alternatives wich work in Java (possibly in-memory out of the box like HSQLDB) for small-scale graphs and still provide a declarative query language like Cypher?

Note that performance is not so much of an issue to me, it's more of a playground to gather some experience with graph databases, but I don't want the application to create a Database file system on disk.


Answer:

Note that performance is not so much of an issue to me,

In that case you can go for ImpermamentGraphDatabase of neo4j, which is created like this:

graphDb = new TestGraphDatabaseFactory().newImpermanentDatabase();

It doesn't create any files on filesystem.

Source:

http://neo4j.com/docs/stable/tutorials-java-unit-testing.html

Question:

I am new to graph database. I am badly confused how to code for it. Either by Cypher Query Language or from java.And what is the use neoeclipse. If i have to code from java and then which packages to import? If Cypher then how to connect it with java?


Answer:

You should start with the neo4j tutorial.

Briefly, cypher is a query language. Once you have data in graphs, you can query it with cypher just like you would use SQL for a regular database. You can also use java, but I don't recommend doing it via java unless you have a requirement that indicates that cypher isn't suitable. Cypher will be easier at first, and will do most of what you want with no java code at all.

Neoeclipse is a tool to view, edit, and explore databases. I've never used it though, as the web front end that comes with neo4j is usually enough for me.

If you want to get started writing java programs with neo4j, start here. If you want to write cypher queries that run in a java program, you can find those documentation items here.

Question:

I have a NodeEntity like the following and I want to use Pathfinder algorithm on it. The algorithm is below. unfortuantely I get the error that neo4j.entity.Stop cannot be cast to org.neo4j.graphdb.Node

What should I do? I dont know how to make spring use the org.neo.graphalgo graphalgo library

private Path testGraphAlgoFactory(Stop s1, Stop s2){

 PathExpander expander = PathExpanders.allTypesAndDirections();

 PathFinder<Path> pathFinder =
                GraphAlgoFactory.shortestPath(expander , 6);

 Path path = pathFinder.findSinglePath((Node)s1, (Node)s2);
}

This is my NodeEntity class as follows:

@NodeEntity
public class Stop {
    @GraphId
    private Long id;

    @Property(name="name")
    private String name;

    @Property(name="lon")
    private double longitude;

    @Property(name="lat")
    private double latitude;

    @Property(name="id")
    private String stopId;
}

Answer:

If you are using OGM to convert the nodes from the graph into objects this is a valid outcome. The classes like Stop are "just" Java classes and do not know that they have any Neo4j origin.

Besides this (and also regarding you other question from earlier this day): the graph algorithms are intended to be used as a plugin in Neo4j and not as part of your application code. Neo4j Graph Algorithms documentation

So it might be easier in your application to use the SessionFactory and get a new Session to run a cypher statement that calls the algorithm on your Neo4j. e.g. CALL algo.shortestPath(...)

Another option could be that you use a custom query in your SpringData Neo4j repository to execute the query statement by using @Query("CALL ..."). But you must know what you will return from your cypher statement. Then you can put the result into a @QueryResult class. Sample from the docs (but do not create an inner class but a class in your entity scan path)

Question:

I have a dataset similar to Twitter's graph. The data is in the following form:

<user-id1> <List of ids which he follows separated by spaces>
<user-id2> <List of ids which he follows separated by spaces>
...

I want to model this in the form of a unidirectional graph, expressed in the cypher syntax as:

(A:Follower)-[:FOLLOWS]->(B:Followee)

The same user can appear more than once in the dataset as he might be in the friend list of more than one person, and he might also have his friend list as part of the data set. The challenge here is to make sure that there are no duplicate nodes for any user. And if the user appears as a Follower and Followee both in the data set, then the node's label should have both the values, i.e., Follower:Followee. There are about 980k nodes in the graph and size of dataset is 1.4 GB.

I am not sure if Cypher's load CSV will work here because each line of the dataset has a variable number of columns making it impossible to write a query to generate the nodes for each of the columns. So what would be the best way to import this data into Neo4j without creating any duplicates?


Answer:

I did actually exactly the same for the friendster dataset, which has almost the same format as yours.

There the separator for the many friends was ":".

The queries I used there, are these:

create index on :User(id);

USING PERIODIC COMMIT 1000
LOAD CSV FROM "file:///home/michael/import/friendster/friends-000______.txt" as line FIELDTERMINATOR ":"
MERGE (u1:User {id:line[0]})
;

USING PERIODIC COMMIT 1000
LOAD CSV FROM "file:///home/michael/import/friendster/friends-000______.txt" as line FIELDTERMINATOR ":"
WITH line[1] as id2
WHERE id2 <> '' AND id2 <> 'private' AND id2 <> 'notfound'
UNWIND split(id2,",") as id
WITH distinct id
MERGE (:User {id:id})
;

USING PERIODIC COMMIT 1000
LOAD CSV FROM "file:///home/michael/import/friendster/friends-000______.txt" as line FIELDTERMINATOR ":"
WITH line[0] as id1, line[1] as id2
WHERE id2 <> '' AND id2 <> 'private' AND id2 <> 'notfound'
MATCH (u1:User {id:id1})
UNWIND split(id2,",") as id 
MATCH (u2:User {id:id})
CREATE (u1)-[:FRIEND_OF]->(u2)
;

Question:

I'm using neo4j 3.1 with java 8 and I want to extract a connected subgraph as to store it as a test database. Is it possible to do it and how? How to do it with the clause Return which returns the output. So, I had to create new nodes and relations or just export the subgraph and put it in a new database.

How can I extract a connected subgraph since I have a disconnected graph.

Thank you


Answer:

There are two parts to this...getting the connected subgraph, and then finding a means to export.

APOC Procedures seems like it can cover both of these. The approach in this answer using the path expander should get you all the nodes in the connected subgraph (if the relationship type doesn't matter, leave off the relationshipFilter parameter).

The next step is to get all relationships between all of those nodes. APOC's apoc.algo.cover() function in the graph algorithms section should accomplish this.

Something like this (assuming this is after the subgraph query, and subgraphNode is in scope for the column of distinct subgraph nodes):

...
WITH COLLECT(subgraphNode) as subgraph, COLLECT(id(subgraphNode)) as ids
CALL apoc.algo.cover(ids) YIELD rel
WITH subgraph, COLLECT(rel) as rels
...

Now that you have the collections of both the nodes and relationships in the subgraph, you can export them.

APOC Procedures offers several means of exporting, from CSV to CypherScript. You should be able to find an option that works for you.

Question:

I'm creating a graph DB of Taxis network storing in each node a taxi with a long list of properties of (date, fee), I'm storing a date in Java DATE format that contains spaces but I cannot access it while matching.

MATCH (t) WHERE t.name='someTaxi' RETURN t.Sun Mar 01 00:00:00 EET 2015;

But this didn't work so I used backtick-ing

I stored property key with backticks like this 'Sun Mar 01 00:00:00 EET 2015' the second time

MATCH (t) WHERE t.name='someTaxi' RETURN t.'Sun Mar 01 00:00:00 EET 2015';

but this didn't work either.

So Is it possible to store a property key like that in Neo4j and How can I return it ?


Answer:

The problem

You are storing some data this way (json representation):

{name: "someTaxi", Sun Mar 01 00:00:00 EET 2015 : fees}

This data model is bad, considering Neo'j's ability to manage such datas using relations.

The solution

You have to create a better data model using Neo4j's power: Relations. Here is an example of what you wan do:

Here is the node details (pseudo cypher representation):

(:Taxi{name:someTaxi})-[:EARNED{date:<Here you set your date>}]->(:Fees{value:<The amount>)

So now, to match your fees, you can simply use this query:

MATCH (t:Taxi{name : <taxi Name>})-[r:EARNED{date: <yourDate>}]->(f:Fees) 
RETURN f.value

Question:

I must create a graph based on the result of a query. After getting the results based on a retrieved column as String ( column that represents a SQL sentence) I need to generate the corresponding graph creation sentences as follows:

Retrieved column:

_fn1(filed1, filed2, filed3, '', filed4, filed5) AS new_alias_field

Sentences to be generated for the graph creation on Neo4j:

CREATE (new_alias_field:fields_from {column:'new_alias_field'})
CREATE (filed1:fields_to{column:'filed1'})
CREATE (filed2:fields_to{column:'filed2'})
CREATE (filed3:fields_to{column:'filed3'})
CREATE (filed4:fields_to{column:'filed4'})
CREATE (filed5:fields_to{column:'filed5'})

CREATE (fn1:function {name:'_fn1'})

  CREATE
  (filed1)-[:used_by {roles:['param']}]->(fn1),
  (filed2)-[:used_by {roles:['param']}]->(fn1),
  (filed3)-[:used_by {roles:['param']}]->(fn1),
  (filed4)-[:used_by {roles:['param']}]->(fn1),
  (filed4)-[:used_by {roles:['param']}]->(fn1)

CREATE
  (fn1)-[:as ]->(new_alias_field)

The best way to accomplish this is creating a parser? or should I use something like JSqlParser since the original string has some SQL statements ? Should I created my own parser? is there any other tool available?

I am trying to use JSqlParser, get the objects and then convert them. Still in progress .

to try the the code in Neo4J, after run the creation script you can query the nodes using :

Match(new_alias_field{column:'new_alias_field'}) return new_alias_field

you must get:


Answer:

JSqlParser is a great parser it uses the visitor pattern. I used to parse this statements using the next expression

select <<statement>> from dual

I only limitation I found was: IF statement used in MSQL aren't supported yet.

Once I parsed this statements I used Spring annotation

@NodeEnityty

To create all the entities and make the insertions, for instance the FieldsFrom node is going to look like:

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@NodeEntity
public class FieldsFrom {
   @Id
   @GeneratedValue
   private Long id;

   private String name;


   @Relationship(type= "USED_BY", direction = Relationship.INCOMING)
   private Set<FieldsTo> fieldsTo;

}

After all the processing, and all the insertions I used https://github.com/neo4j-contrib/neovis.js

Question:

By using findAll() from GraphRepository<Account>:

    context = new ClassPathXmlApplicationContext("spring/spring-config.xml");
    accountService = (AccountService) context.getBean("accountService");

    //getAll(){return accountRepository.findAll()}

    accountService.getAll().forEach(account -> System.out.println(account));

(btw. all other functions from my accountService works)

I getting this error:

 Exception in thread "main" org.neo4j.graphdb.TransactionFailureException: 
 Failed to mark transaction as rollback only.

I try to fix the problem with: Spring Data Neo4J repository findAll() results in a nullpointerexception , so i add <tx:annotation-driven mode="proxy"/> in my spring-config.xml but it doesn't fix my problem.

here my github repo: https://github.com/mzober/springContextWorld/tree/CollectorManager_ErrorBranch

Here my spring-config.xml:

 <beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
   xmlns:tx="http://www.springframework.org/schema/tx"
   xsi:schemaLocation=
           "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context.xsd
   http://www.springframework.org/schema/data/neo4j
    http://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:annotation-config/>
<context:spring-configured/>

<context:component-scan base-package="com.mz.springContextWorld.domain"/>
<context:component-scan base-package="com.mz.springContextWorld.repositories"/>
<context:component-scan base-package="com.mz.springContextWorld.gui.listener"/>
<context:component-scan base-package="com.mz.springContextWorld.gui.components"/>
<context:component-scan base-package="com.mz.springContextWorld.gui.creational"/>
<context:component-scan base-package="com.mz.springContextWorld.services"/>

<neo4j:config storeDirectory="target/neo4j-db-plain"
              base-package="com.mz.springContextWorld.domain"/>
<neo4j:repositories base-package="com.mz.springContextWorld.repositories"/>

<tx:annotation-driven mode="proxy"/>

If i should post more code pls write a comment.

ty for helping.


Answer:

This is probably related to the issue: https://jira.spring.io/browse/DATAGRAPH-531. If that's the case, you need to change

service.findAll()

to:

service.findAll().as(Collection.class)

... and the rollback exception should go away.

Question:

When I write the following Neo4j Cypher query in Java:

propertiesQuery = new StringBuilder();
propertiesQuery.append("MATCH (si)-[r]->(so) WHERE r.name = $rName  ");
propertiesQuery.append("SET ");
String g = "None";
propertiesQuery.append("r.flow");
propertiesQuery.append("=");
propertiesQuery.append(g);  

and execute the propertiesQuery statement, it gives me the following error:

org.neo4j.graphdb.QueryExecutionException: Variable 'None' not defined

when in reality None is the value of the string variable g. Can somebody please explain the error here ( I already initialized the required parameters - so that is not the error)?


Answer:

The Cypher query needs to specify a string literal.

Try changing:

String g = "None";

to:

String g = "'None'";

Question:

Can anyone exmplain the difference betwen @GraphId and @Index annotation from org.neo4j.ogm.annotation ? For now, after reading the docs it seems that @GraphId is used to create identifier for Neo4j internal logic and users should not rely on that, because it can be reused over time. But what about @Index?

As I understand, the main advantage of graph based databases is that once we know the node/relation from which to start things become easy, since all we need to do is just traverse the graph from that starting node. And indexing helps to do so, right? So, we can write something like START n = node:index_name(property_name = value) and immitiately start exloring the graph from the indexed node by 'property_name' property, right?

So, consider this entity :

@ToString
@NodeEntity(label = "Event")
@NoArgsConstructor
public class Event{

    public Event(String eventName, LocalDate dateTime){
        this.name = eventName;
        this.date = dateTime;
    }

    public Event(Long id, String eventName, LocalDate dateTime){
        this(eventName, dateTime);
        this.id = id;
    }

    @Getter
    @GraphId
    private Long id;

    @Getter
    @Index(unique = true, primary = true)
    @Property(name = "name")
    private String name;

    @Getter
    @Property(name = "date")
    @Convert(DateConverter.class)
    private LocalDate date;
}

As you can see the String name property is annotated with @Index. How can I write Cypher query to actually start from the node with name = 'something'? What is the index name? Or does Spring Data Neo4j 4.2.0.RELEASE figure it itself when write just MATCH (event:Event {name = 'somehting'} ... ?

@Repository
public interface EventRepository extends Neo4jRepository<Event, String>{

    Event findOne(String eventName);

}

Here the repositry class and as you might see I am using String as the type of the id of the entity the repository manages, so I assume Spring uses name property of Event class to generate a query for Event findOne(String eventName);


Answer:

@Index is similar to @Indexed if your are familiar with spring-data-mongodb or @Index in spring-data-jpa. Basically it indexes the field(among other things) which makes it searching for this field quite fast. Regarding your repository method, it should be named like this

Event findByName(String eventName);

Question:

I want to insert a string parameter to a cypher query in Java. Below is the code I used and I have a person node named 'piyumi' and I want to make relationship with an activity node. The name of the activity node is 'walking'. When I execute the code I get http status code 400. Can anyone help me to modify the cypher query so that I can insert the string variable s without error.

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;

import javax.ws.rs.core.MediaType;

public class NeoAPIClass {
    private final String baseUri = "http://localhost:7474/db/data/cypher";
    private final String user = "neo4j";
    private final String password = "12345";

    public static void main(String args[]) throws JSONException {
            NeoAPIClass n=new NeoAPIClass();
            n.runQuery();
    }

    void runQuery() throws JSONException {
        Client client = Client.create();
        client.addFilter(new HTTPBasicAuthFilter(user, password));
        WebResource cypherResource = client.resource(baseUri);


        String s="walking";
        JSONObject obj = new JSONObject();
        obj.put("query", "Match(piyumi : Person{name:\"Piyumi\"}) create (piyumi)-[:doing{timestamp:4789}]->(n:activity) WHERE n.name=s");
        String st = obj.toString();

        ClientResponse cypherResponse = cypherResource.accept(MediaType.APPLICATION_JSON)
                .type(MediaType.APPLICATION_JSON_TYPE).entity(st).post(ClientResponse.class);

        System.out.println("Output from Server .... "+ cypherResponse.getStatus());


    }

}

Answer:

It is impossible to combine the create and where. You need first match person and activity, and then create a relationship.

And also recommend to simplify the transfer parameters in a separate part of the request (https://neo4j.com/docs/rest-docs/current/#rest-api-use-parameters):

JSONObject request = new JSONObject();
JSONObject params =  new JSONObject();

String query =  "MATCH (P:Person { name:{personName} }) \n";
query = query + "MATCH (A:activity { name:{activityName} }) \n";
query = query + "CREATE (P)-[rel:doing { timestamp:{activityTimestamp} }]->(A) \n";
query = query + "RETURN P, A, rel";

request.put("query", query);

params.put("personName", "Piyumi");
params.put("activityName", "walking");
params.put("activityTimestamp", 4789);

request.put("params", params);

ClientResponse cypherResponse = cypherResource.accept(MediaType.APPLICATION_JSON)
            .type(MediaType.APPLICATION_JSON_TYPE)
            .entity(request.toString())
            .post(ClientResponse.class);

System.out.println("Response: " + cypherResponse.getEntity(String.class));

Question:

@NodeEntity
class A {
    @Relationship(type = "INCLUDES", direction = Relationship.UNDIRECTED)
    List<B> bs;
}

@NodeEntity
class B {}

class C {
    int something;
}

@RelationshipEntity(type = "INCLUDES")
class R {
    String property1;
    int property2;
    C c;

    @StartNode
    A a;

    @EndNode
    B b;
}

The goal to retrieve the relationship entity between two particular nodes (some instances of Aand B) with ALL its properties.

I tried the following cypher query:

MATCH (a:A)-[i:INCLUDES]-(b:B) RETURN i;

However, this only gives me an empty result. If I retrieve all INCLUDErelationship entities with the default Neo4jRepository.findAll() implementation, I can see that all properties are set.

Thanks for any help!


Answer:

Try this

MATCH (a:A)-[i:INCLUDES]-(b:B) RETURN i, a, b;

Question:

I am very new to CYPHER QUERY LANGUAGE AND i am working on relationships between nodes. I have a CSV file of table containing multiple columns and 1000 rows. Template of my table is :

cdrType    ANUMBER    BNUMBER    DUARTION    
2          123        456        10 
2          890        456        5 
2          123        666        2 
2          123        709        7 
2          345        789        20 

I have used these commands to create nodes and property keys.

LOAD CSV WITH HEADERS FROM "file:///2.csv" AS ROW
CREATE (:ANUMBER {aNumber:ROW.aNumber} ),
CREATE (:BNUMBER {bNumber:ROW.bNumber} )

Now I need to create relation between all rows in the table and I think FOREACH loop is best in my case. I created this query but it gives me an error. Query is :

MATCH (a:ANUMBER),(b:BNUMBER)
FOREACH(i in RANGE(0, length(ANUMBER)) | 
    CREATE UNIQUE (ANUMBER[i])-[s:CALLED]->(BNUMBER[i]))

and the error is :

Invalid input '[': expected an identifier character, whitespace, NodeLabel, a property map, ')' or a relationship pattern (line 3, column 29 (offset: 100)) " CREATE UNIQUE (a:ANUMBER[i])-[s:CALLED]->(b:BNUMBER[i]))"

I need relation for every row. like in my case. 123 - called -> 456 , 890 - called -> 456. So I need visual representation of this calling data that which number called which one. For this I need to create relation between all rows.

any one have idea how to solve this ?


Answer:

What about :

LOAD CSV WITH HEADERS FROM "file:///2.csv" AS ROW
CREATE (a:ANUMBER {aNumber:ROW.aNumber} )
CREATE (b:BNUMBER {bNumber:ROW.bNumber} )
MERGE (a)-[:CALLED]->(b);

It's not more complex than that i.m.o.

Hope this helps !

Regards, Tom

Question:

I asked this question How to get subgraph a while back and found while it does give me all nodes and relationships at the Nth level, the answers assume the direction of the relationships either fan out from the starting node or converge to the node. What I am looking for is a complete subgraph that captures all relationships and nodes at a certain level while preserving and relating the direction of the relationships.

For example, if I want all nodes and relationships at depth 2 I can make a directionless query as follows:

START n=node(12345) MATCH (n)<-[r*1..2]->(m) RETURN r, m;

This works well as I get all nodes and all relationships, but I find I have no idea what direction the relationships are in.

If I limit the search to a depth of 1 and perform two searches, one incoming and one outgoing, I can get all nodes and relationships with direction that way. I can then recursively do the same query for all nodes found at depth two, discarding any relationships that contain nodes not found beyond the 2nd level from the start. This seems rather painful and manual but it works.

I've also tried using the TraversalDescription framework in the embedded Java API, but that doesn't quite return all relationships. For example, the following snippet gave me all nodes at depth 2, but it missed some relationships between nodes at depth 2:

for ( Path position : graphDb.traversalDescription() .breadthFirst() .evaluator( Evaluators.toDepth( 2 ) ) .traverse( templateNode ) ) { output += position + "\n"; }

Is there an easy way to do this without multiple manual iterations?


Answer:

Directionless queries are without arrow tips.

If you want to have a direction use:

START n=node(12345)
 MATCH (n)-[r*1..2]->(m)
 RETURN r, m;

You can access start and endnode of the rel and then output them to infer their direction.

START n=node(12345)
 MATCH (n)-[rels*1..2]->(m)
 RETURN m, extract(r in relsĀ | [startNode(r),endNode(r),type(r)]);

Question:

I know this is probably asked a hundred times and believe me, I read soooo much on the net already. But still, I am absolutely unapt to do this, so I'm in dire need of help here.

What I want to do, is to create a node with label and properties in the neo4j db using cypher and the transactional endpoint - with the properties from a json.

This is my code so far:

/**
 * 
 * @description creates a node in the graph 
 * @param       json object
 * @param       label
 * 
 */
private String createNodeObjectTransactional(JSONObject nodeObject, GraphNodeTypes label){
    String nodeLocation=null;
    try{
        dbServerUrl = "http://localhost:7474"
        transactionUrl = dbServerUrl + "/db/data" + "/transaction";
        String finalUrl = transactionUrl;

        String payload = "{\"statements\": [ {\"statement\": \"CREATE\" (p:"+ label.toString() +" "+ nodeObject.toString() + ") } ] }";

        logger.trace("sending cypher {} to endpoint {}", payload, finalUrl);
        WebResource resource = Client.create().resource( finalUrl );

        ClientResponse response = resource
                .accept( MediaType.APPLICATION_JSON )
                .type( MediaType.APPLICATION_JSON )
                .entity( payload )
                .post( ClientResponse.class );

        nodeLocation = response.getLocation().toString();

        String responseString = response.getEntity(String.class);

        logger.debug("POST to {} returned status code {}, returned data: {}",
                finalUrl, response.getStatus(),
                responseString);

        // first check if the http code was ok
        HttpStatusCodes httpStatusCodes = HttpStatusCodes.getHttpStatusCode(response.getStatus());
        if (!httpStatusCodes.isOk()){
            if (httpStatusCodes == HttpStatusCodes.FORBIDDEN){
                logger.error(HttpErrorMessages.getHttpErrorText(httpStatusCodes.getErrorCode()));
            } else {
                logger.error("Error {} sending data to {}: {} ", response.getStatus(), finalUrl, HttpErrorMessages.getHttpErrorText(httpStatusCodes.getErrorCode()));
            }
        } else {
            // now do the check on json details within the returned JSON object
            JSONParser reponseParser = new JSONParser();
            Object responseObj = reponseParser.parse(responseString);
            JSONObject jsonResponseObj = responseObj instanceof JSONObject ?(JSONObject) responseObj : null;
            if(jsonResponseObj == null)
                throw new ParseException(0, "returned json object is null");

            // this is the location to commit the transaction if node creation was successfull
            String commit = (String) jsonResponseObj.get("commit").toString();
            // this contains an error object (actually an array) in case the creation was NOT successfull
            String error = (String) jsonResponseObj.get("errors").toString();
            // doknow what that is
            String result = (String) jsonResponseObj.get("results").toString();

            final URI location = response.getLocation();

            if (error.isEmpty()) {
                logger.info("new node created at location {}", location);
                logger.trace("returned result json is {}", result.toString());
                logger.debug("committing transaction at location {}", commit);
                resource = Client.create().resource( commit );
                response = resource
                        .accept( MediaType.APPLICATION_JSON )
                        .type( MediaType.APPLICATION_JSON )
                        .post( ClientResponse.class );
                logger.debug("COMMIT returned status code {}, returned data: {}",
                        response.getStatus(),
                        response.getEntity(String.class));
            } else {
                logger.error("ERROR :: {} - could not create node at location {}", error.substring(13), location);
                logger.trace("returned error json is {}", error.toString());
            }
        }
        response.close();

    } catch(Exception e) {
        logger.error("EXCEPTION :: failed to create node - {}", e.getMessage());
        e.printStackTrace();
    }

    return nodeLocation;
}

and this is the server's response:

ERROR :: Unable to deserialize request: Unexpected character ('(' (code 40)): was expecting comma to separate OBJECT entries\n at [Source: org.eclipse.jetty.server.HttpConnection$Input@44382113{HttpChannelOverHttp@41038962{r=6,a=DISPATCHED,uri=\/db\/data\/transaction},HttpConnection@4f30a246{FILLING},g=HttpGenerator{s=START},p=HttpParser{s=END,275 of 275}}; line: 1, column: 42]","code":"Neo.ClientError.Request.InvalidFormat"}] - could not create node at location http://localhost:7474/db/data/transaction/121

What really bothers me about this, is that in the examples given on the neo4j site, they DO put in the ( character to encapsulate the label and json object, but the server does not like that character. As stated in the answer:

Unexpected character ('(' (code 40)): was expecting comma to separate OBJECT

I have no idea, what the server means by adding a comma at this location. It is not within the son of the object but rather precedes that.

Here comes the tracelog:

INFO  Neo4JPersistence - creating a Twitter node object to store in the graph
DEBUG Neo4JPersistence - creating node transactional
TRACE Neo4JPersistence - sending cypher payload {"statements": [ {"statement": "CREATE" (p:POST {"id":"534621287264817153","subject":"daily....","teaser":"daily...","lang":"de","sn_id":"TW"}) } ] } to endpoint http://localhost:7474/db/data/transaction
DEBUG Neo4JPersistence - POST to http://localhost:7474/db/data/transaction returned status code 201, returned data: {"commit":"http://localhost:7474/db/data/transaction/121/commit","results":[],"transaction":{"expires":"Tue, 18 Nov 2014 08:19:55 +0000"},"errors":[{"code":"Neo.ClientError.Request.InvalidFormat","message":"Unable to deserialize request: Unexpected character ('(' (code 40)): was expecting comma to separate OBJECT entries\n at [Source: org.eclipse.jetty.server.HttpConnection$Input@44382113{HttpChannelOverHttp@41038962{r=6,a=DISPATCHED,uri=/db/data/transaction},HttpConnection@4f30a246{FILLING},g=HttpGenerator{s=START},p=HttpParser{s=END,275 of 275}}; line: 1, column: 42]"}]}
ERROR Neo4JPersistence - ERROR :: Unable to deserialize request: Unexpected character ('(' (code 40)): was expecting comma to separate OBJECT entries\n at [Source: org.eclipse.jetty.server.HttpConnection$Input@44382113{HttpChannelOverHttp@41038962{r=6,a=DISPATCHED,uri=\/db\/data\/transaction},HttpConnection@4f30a246{FILLING},g=HttpGenerator{s=START},p=HttpParser{s=END,275 of 275}}; line: 1, column: 42]","code":"Neo.ClientError.Request.InvalidFormat"}] - could not create node at location http://localhost:7474/db/data/transaction/121
TRACE Neo4JPersistence - returned error json is [{"message":"Unable to deserialize request: Unexpected character ('(' (code 40)): was expecting comma to separate OBJECT entries\n at [Source: org.eclipse.jetty.server.HttpConnection$Input@44382113{HttpChannelOverHttp@41038962{r=6,a=DISPATCHED,uri=\/db\/data\/transaction},HttpConnection@4f30a246{FILLING},g=HttpGenerator{s=START},p=HttpParser{s=END,275 of 275}}; line: 1, column: 42]","code":"Neo.ClientError.Request.InvalidFormat"}]

Please, please please,

can anyone help me?

Thanks in advance,

Chris


Answer:

As the error tells you, you are passing malformed json

... "CREATE" (p:POST ...

Json should be as described here

{
  "statements" : [ {
    "statement" : "CREATE (n {props}) RETURN n",
    "parameters" : {
      "props" : {
        "name" : "My Node"
      }
    }
  } ]
}

(See docs for details)

In your case:

String payload = "{\"statements\": 
    [ {\"statement\": \"CREATE (p:"+ label.toString() +" " {props}) \", 
       \"parameters\":" + nodeObject.toString() + " } ] }";

Question:

I'm having some trouble using Neoclipse with my Neo4j server. I can connect to the db without any issues but as soon as the connection is established it throws two error boxes simultaneously.

If I click OK and continue I'm presented with an empty database graph view.

If I click the home icon to show reference node I'm getting this error:

After reading around it seems it might be something to do with the reference node at location zero but I'm not sure whether this was even created in this version of Neo4j (3.0.3); it's not present. I read that this approach was deprecated or even removed?

Do I need to create a reference node in order to be able to use Neoclipse? If so how do I do so? I'm interacting with the db in java using the neo4j-java-driver.

Thanks for any help and advice!


Answer:

Recent versions of neo4j (some time after 2.3.x) started enforcing the requirement that nodes (in Cypher) be specified within parentheses.

neoclipse was last updated 2 years ago to conform to neo4j 2.1.4, and does not always use parentheses for nodes when making Cypher queries. So, it will not work with neo4j 3.x.

If you need to use neoclipse, you would either have to modify its code, or downgrade your neo4j service to an older version.

Question:

I downloaded java jdk1.8.0_25

but when trying to install neo4j 2.2.2 community zip by this link http://www.tutorialspoint.com/neo4j/neo4j_zip_environment_setup.htm

it's giving me eror

C:>Neo4j.bat

ERROR! You are using an unsupported version of Java, please use Oracle HotSpot 1 .7. 2015-06-21 17:31:52.146+0000 INFO [API] Setting startup timeout to: 120000ms ba sed on 120000 2015-06-21 17:31:53.718+0000 INFO [API] Successfully shutdown Neo4j Server. Can't load log handler "java.util.logging.FileHandler" java.nio.file.NoSuchFileException: data\log\windows-wrapper.0.0.log.lck java.nio.file.NoSuchFileException: data\log\windows-wrapper.0.0.log.lck at sun.nio.fs.WindowsException.translateToIOException(WindowsException.j ava:79) at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.jav a:97) at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.jav a:102) at sun.nio.fs.WindowsFileSystemProvider.newFileChannel(WindowsFileSystem Provider.java:115) at java.nio.channels.FileChannel.open(FileChannel.java:287) at java.nio.channels.FileChannel.open(FileChannel.java:335) at java.util.logging.FileHandler.openFiles(FileHandler.java:438) at java.util.logging.FileHandler.(FileHandler.java:255) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstruct orAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingC onstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:408) at java.lang.Class.newInstance(Class.java:438) at java.util.logging.LogManager$5.run(LogManager.java:966) at java.security.AccessController.doPrivileged(Native Method) at java.util.logging.LogManager.loadLoggerHandlers(LogManager.java:958) at java.util.logging.LogManager.initializeGlobalHandlers(LogManager.java :1578) at java.util.logging.LogManager.access$1500(LogManager.java:145) at java.util.logging.LogManager$RootLogger.accessCheckedHandlers(LogMana ger.java:1667) at java.util.logging.Logger.getHandlers(Logger.java:1776) at java.util.logging.Logger.log(Logger.java:735) at java.util.logging.Logger.doLog(Logger.java:765) at java.util.logging.Logger.log(Logger.java:788) at java.util.logging.Logger.info(Logger.java:1489) at org.neo4j.wrapper.NeoServiceWrapper.launchAsConsoleApp(NeoServiceWrap per.java:49) at org.neo4j.wrapper.NeoServiceWrapper.main(NeoServiceWrapper.java:35) Jun 21, 2015 11:01:55 PM org.neo4j.wrapper.NeoServiceWrapper launchAsConsoleApp INFO: Params Jun 21, 2015 11:01:55 PM org.neo4j.wrapper.NeoServiceWrapper launchAsConsoleApp INFO: -Dorg.neo4j.server.properties="conf/neo4j-server.properties" Jun 21, 2015 11:01:55 PM org.neo4j.wrapper.NeoServiceWrapper launchAsConsoleApp INFO: -Djava.util.logging.config.file="conf/logging.properties" Jun 21, 2015 11:01:55 PM org.neo4j.wrapper.NeoServiceWrapper launchAsConsoleApp INFO: -Dlog4j.configuration="file:conf/log4j.properties" Jun 21, 2015 11:01:55 PM org.neo4j.wrapper.NeoServiceWrapper launchAsConsoleApp INFO: "-XX:+UseConcMarkSweepGC" Jun 21, 2015 11:01:55 PM org.neo4j.wrapper.NeoServiceWrapper launchAsConsoleApp INFO: "-XX:+CMSClassUnloadingEnabled" Jun 21, 2015 11:01:55 PM org.neo4j.wrapper.NeoServiceWrapper launchAsConsoleApp INFO: "-XX:-OmitStackTraceInFastThrow" Jun 21, 2015 11:01:55 PM org.neo4j.wrapper.NeoServiceWrapper launchAsConsoleApp INFO: "-XX:hashCode=5" Jun 21, 2015 11:01:55 PM org.neo4j.wrapper.NeoServiceWrapper launchAsConsoleApp INFO: -Dneo4j.ext.udc.source="zip" Jun 21, 2015 11:01:55 PM org.neo4j.wrapper.NeoServiceWrapper launchAsConsoleApp INFO: Classpath: "-classpath" "C:\PROGRA~1\NEO4J-~1.2\bin..\lib\concurrentlinkedhashmap-lru-1.4.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\lib\lucene-core-3.6.2.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\lib\neo4j-consistency-check-2.2.2.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\lib\neo4j-csv-2.2.2.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\lib\neo4j-cypher-2.2.2.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\lib\neo4j-cypher-compiler-1.9-2.0.4.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\lib\neo4j-cypher-compiler-2.0-2.0.4.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\lib\neo4j-cypher-compiler-2.1-2.1.8.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\lib\neo4j-cypher-compiler-2.2-2.2.2.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\lib\neo4j-graph-algo-2.2.2.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\lib\neo4j-graph-matching-2.2.2.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\lib\neo4j-import-tool-2.2.2.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\lib\neo4j-io-2.2.2.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\lib\neo4j-jmx-2.2.2.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\lib\neo4j-kernel-2.2.2.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\lib\neo4j-lucene-index-2.2.2.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\lib\neo4j-primitive-collections-2.2.2.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\lib\neo4j-shell-2.2.2.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\lib\neo4j-udc-2.2.2.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\lib\neo4j-unsafe-2.2.2.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\lib\opencsv-2.3.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\lib\org.apache.servicemix.bundles.jline-0.9.94_1.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\lib\parboiled-core-1.1.7.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\lib\parboiled-scala_2.10-1.1.7.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\lib\scala-library-2.10.5.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\lib\server-api-2.2.2.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\bcprov-jdk16-140.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\commons-beanutils-1.8.3.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\commons-compiler-2.6.1.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\commons-configuration-1.10.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\commons-digester-2.1.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\commons-io-2.4.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\commons-lang-2.6.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\commons-logging-1.1.1.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\jackson-core-asl-1.9.13.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\jackson-jaxrs-1.9.13.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\jackson-mapper-asl-1.9.13.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\janino-2.6.1.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\javax.servlet-api-3.1.0.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\jcl-over-slf4j-1.7.7.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\jersey-core-1.18.1.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\jersey-multipart-1.18.1.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\jersey-server-1.18.1.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\jersey-servlet-1.18.1.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\jetty-http-9.2.4.v20141103.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\jetty-io-9.2.4.v20141103.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\jetty-security-9.2.4.v20141103.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\jetty-server-9.2.4.v20141103.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\jetty-servlet-9.2.4.v20141103.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\jetty-util-9.2.4.v20141103.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\jetty-webapp-9.2.4.v20141103.jar;C:\PROGRA~1\NEO 4J-~1.2\bin..\system\lib\jetty-xml-9.2.4.v20141103.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\jsr311-api-1.1.2.r612.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\logback-access-1.1.2.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\logback-classic-1.1.2.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\logback-core-1.1.2.jar; C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\mimepull-1.9.3.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\neo4j-browser-2.2.2.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\neo4j-server-2.2.2-static-web.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\neo4j-server-2.2.2.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\rhino-1.7R4.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\rrd4j-2.2.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\scala-reflect-2.10.5.jar;C:\PROGRA~1\NEO4J-~1.2\bin..\system\lib\slf4j-api-1.7.7.jar;C:\PROGRA~1\NEO4J-~1.2\bin...\conf;" Jun 21, 2015 11:01:55 PM org.neo4j.wrapper.NeoServiceWrapper launchAsConsoleApp INFO: Main class: org.neo4j.server.Bootstrapper Jun 21, 2015 11:01:55 PM org.neo4j.wrapper.NeoServiceWrapper launchAsConsoleApp INFO: Args:

C:>

does its only support java 1.7?? but i see neo4j documentation its says that it supports 1.8 also


Answer:

Neo4j 2.2.2 does support Java 8, the compatibility error message is incorrect (see Is neoj4 2.2.2 supporting java 8?, error on neo4j/bin/utils script)

As for the log file, it should log to NEO4J_HOME/data/log, perhaps you have no permissions?

Question:

I have a very rare problem. I have a java program that inserts into A NEO4j database. The program is working fine on my local_host environment, but when I deployed it to the server(where the neo4j is located) the DB is not updated . Here is what I do

//First delete the DB
ExecutionEngine engine = new ExecutionEngine(db);       
engine.execute("MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r");

Transaction tx = db.beginTx();
//insertion here
tx.success();
tx.close();

//look if it was correctly updated
System.out.println("NODES: " + engine.execute("START n=node(*) RETURN     count(n)").dumpToString());
System.out.println("RELATIONSHIPS: " +engine.execute("START r=relationship(*) RETURN count(r)").dumpToString());
db.shutdown();

If I look at the logs everything is working fine

UPDATED
NODES: +----------+
| count(n) |
+----------+
| 99       |
+----------+
1 row

RELATIONSHIPS: +----------+
| count(r) |
+----------+
| 76       |
+----------+
1 row

But when I look into the Neo4J Db via the browser nothing has happened the previous results are still there!. Keep in notice that if I run the same program on my Local_host environment the behavior is the same but in this occasion it is correctly updated

Thank you in advance


Answer:

Thank you for your advice I solved the problem.The issue was the route to the Neo4J DB. When you are running your neo4j program in the same instance where the Neo4J DB is located, you have to specify the path to the folder not the IP. It was actually creating a new neo4j naming it by the IP.

I used

public final static String CONEXION_NEO4J = "/folder/of/neo4jdb/database.db";
GraphDatabaseService db = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder(CONEXION_NEO4J)

instead of

public final static String CONEXION_NEO4J = "//X.X.X.X/neo4j/database.db";
GraphDatabaseService db = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder(CONEXION_NEO4J)

Regards

Question:

I have created 2 classes with same ClassName but in different packages and with different NodeEntity Labels. I'm facing below OGM Mapping Exception, only when invoking a repository method using @Query.

Caused by: org.neo4j.ogm.exception.core.MappingException: More than one class has simple name: Circuit
    at org.neo4j.ogm.metadata.DomainInfo.getClassInfo(DomainInfo.java:307)
    at org.neo4j.ogm.metadata.DomainInfo.getClassSimpleName(DomainInfo.java:289)
    at org.neo4j.ogm.metadata.MetaData.classInfo(MetaData.java:78)
    at org.neo4j.ogm.session.delegates.ExecuteQueriesDelegate.lambda$executeAndMap$1(ExecuteQueriesDelegate.java:119)
    at org.neo4j.ogm.session.Neo4jSession.doInTransaction(Neo4jSession.java:574)
    at org.neo4j.ogm.session.Neo4jSession.doInTransaction(Neo4jSession.java:553)
    at org.neo4j.ogm.session.delegates.ExecuteQueriesDelegate.executeAndMap(ExecuteQueriesDelegate.java:118)
    at org.neo4j.ogm.session.delegates.ExecuteQueriesDelegate.query(ExecuteQueriesDelegate.java:88)
    at org.neo4j.ogm.session.Neo4jSession.query(Neo4jSession.java:408)

On debugging, I have found that the executeAndMap method in org.neo4j.ogm.session.delegates.ExecuteQueriesDelegate class is using the Class SimpleName, and not the assigned label, to find the ClassInfo, which is causing the issue.

The classes with same simple name are present in different packages, with different labels and mapped with different repository interfaces. The Neo4jSession.loadAll works as expected as it uses the class full-qualified-name to get the ClassInfo.

private <T> Iterable<T> executeAndMap(Class<T> type, String cypher, 
                Map<String, ?> parameters, ResponseMapper mapper) {

        return session.<Iterable<T>>doInTransaction( () -> {
            if (type != null && session.metaData().classInfo(type.getSimpleName()) != null) {

Expected: NodeEntity Label to be used to get the ClassInfo.

Actual: Class SimpleName is being used to get the ClassInfo.


Answer:

Using Class FullQualifiedName to get the ClassInfo works perfectly.

It has been fixed. Reference below,

Mapping Exception for entities with same Simple ClassName but different Labels

Question:

I have written a Java program to create graphs in Neo4j and I followed the below tutorial. The Java program works perfectly and does create nodes and relationships. I have written another Java program to cross check the data using Java Cypher API.

https://www.tutorialspoint.com/neo4j/neo4j_native_java_api_example.htm

So, I have below code to create the database:

public static File Neo4j_DB = new File("C:/TPNeo4jDB/databases/graph.db");

public static GraphDatabaseFactory dbFactory = new GraphDatabaseFactory();

public static GraphDatabaseService graphDb= 
                                 dbFactory.newEmbeddedDatabase(Neo4j_DB);

But I am using Neo4j 3.3 and after downloading the zip version, I do not see Neo4j community edition dialog box that would help me to browse through the database created. So, when I go to http://localhost:7474/browser/, I do not see any data as it is still pointing to the default database. I tried changing the configuration file but it is not working but it seems I am not doing it correctly.


Answer:

In your neo4j.conf file, you need to set these 2 properties appropriately:

  • dbms.directories.data

    • This must specify a directory path.
    • This path must have a databases subdirectory (but that subdirectory must not be included in the dbms.directories.data value).
  • dbms.active_database

    • This must be the directory containing the actual neo4j graph DB (i.e., it contains the indexes and data files).
    • This directory must be a child of the above-mentioned databases directory.

Question:

I had created a GraphDatabaseService and created a node.

org.neo4j.graphdb.GraphDatabaseService graphDb = new GraphDatabaseFactory().newEmbeddedDatabase(DB_PATH);

org.neo4j.graphdb.Node customer=graphDb.createNode();

Now I require to add a label to the node to identify that the node as customer.

Could anyone please guide me?


Answer:

Neo4j Labels are not supported for Neo4j 1.x. They were introduced in Neo4j 2.

For more info, check out

Therefore, what you are asking is not possible without upgrading to Neo4j 2.x.

Question:

What is the neo4j-rest-graphdb version which supports neo4j-community-2.3.0-M02 version? I'm already checked 2.0.0-M06,2.0.0 and 2.0.1 versions but all gives following exception.

java.lang.RuntimeException: Error reading as JSON ''
at org.neo4j.rest.graphdb.util.JsonHelper.readJson(JsonHelper.java:57)
at org.neo4j.rest.graphdb.util.JsonHelper.jsonToSingleValue(JsonHelper.java:62)
at org.neo4j.rest.graphdb.RequestResult.toEntity(RequestResult.java:114)
at org.neo4j.rest.graphdb.RequestResult.toMap(RequestResult.java:120)
at org.neo4j.rest.graphdb.batch.CypherResult.<init>(CypherResult.java:43)
at org.neo4j.rest.graphdb.ExecutingRestAPI.query(ExecutingRestAPI.java:554)
at org.neo4j.rest.graphdb.ExecutingRestAPI.query(ExecutingRestAPI.java:574)
at org.neo4j.rest.graphdb.RestAPIFacade.query(RestAPIFacade.java:235)
at org.neo4j.rest.graphdb.query.RestCypherQueryEngine.query(RestCypherQueryEngine.java:50)

I have no control on db versions so I can't upgrade or downgrade neo4j db version. I'm already spent 2-3 days on this problem so anyone knows a solution for this please help me.


Answer:

Quoting @MichaelHunger (Best solution for multiple queries in a limited time):

I would not recommend RestGraphDatabase and friends, because it is slow and outdated.

I think there's no good neo4j-rest-graphdb version for Neo4j 2.3 since it's no longer maintained so you may have to switch to another connector (jdbc-neo4j is maintained)