简体   繁体   中英

Is it possible to have different types of nodes in a neo4j graph database

for example, if I have two nodes created in a transaction

node1 = db.graphDb.createNode();
node2 = db.graphDb.createNode();

// index user id
node1.setProperty("abc", "fkdjasflasdjlf");
db.nodeIndex.add(node1, "abc", "fkdjasflasdjlf");

node1 has property "abc" but node2 doesn't.

Then I tried to query on nodes, like list all the nodes that have property "abc" equals "fkdjasflasdjlf".

ExecutionResult result = engine.execute("START n=node(*) WHERE n.abc = 'fkdjasflasdjlf' return n ");

Neo4j generates exceptions

Exception in thread "main" org.neo4j.cypher.EntityNotFoundException: The property 'abc' does not exist on Node[0]
at org.neo4j.cypher.internal.commands.expressions.Property.apply(Property.scala:35)
at org.neo4j.cypher.internal.commands.expressions.Property.apply(Property.scala:29)
at org.neo4j.cypher.internal.commands.Equals.isMatch(ComparablePredicate.scala:60)
at org.neo4j.cypher.internal.pipes.FilterPipe$$anonfun$createResults$1.apply(FilterPipe.scala:29)
at org.neo4j.cypher.internal.pipes.FilterPipe$$anonfun$createResults$1.apply(FilterPipe.scala:29)
at scala.collection.Iterator$$anon$22.hasNext(Iterator.scala:390)
at scala.collection.Iterator$$anon$19.hasNext(Iterator.scala:334)
at scala.collection.Iterator$$anon$19.hasNext(Iterator.scala:334)
at org.neo4j.cypher.PipeExecutionResult.hasNext(PipeExecutionResult.scala:138)
at scala.collection.Iterator$$anon$19.hasNext(Iterator.scala:334)
at scala.collection.JavaConversions$IteratorWrapper.hasNext(JavaConversions.scala:562)
at neo4j.TestNodeSearch.main(TestNodeSearch.java:59)
    Caused by: org.neo4j.graphdb.NotFoundException: 'abc' property not found for NodeImpl#0.
at       
    org.neo4j.kernel.impl.core.Primitive.newPropertyNotFoundException(Primitive.java:184)
at org.neo4j.kernel.impl.core.Primitive.getProperty(Primitive.java:179)
at org.neo4j.kernel.impl.core.NodeImpl.getProperty(NodeImpl.java:52)
at org.neo4j.kernel.impl.core.NodeProxy.getProperty(NodeProxy.java:155)
at org.neo4j.cypher.internal.commands.expressions.Property.apply(Property.scala:33)

So is there any way to support "different types" of nodes or currently, only one type of node is supported?

Thanks a lot!

As others have pointed out, you need to verify that the abc property exists on the node before evaluating its value, or else an exception is thrown. There are two ways to do this:

  1. Using the has function :

    START n=node(*) WHERE has(m.abc) AND n.abc = 'fkdjasflasdjlf' return n

  2. Using the ! property operator (which evaluates to false for missing properties).

    START n=node(*) WHERE n.abc! = 'fkdjasflasdjlf' return n

As a general note, nodes in Neo4j are typeless/schemaless. A node either does or does not have a property you're looking for, you just need to appropriately handle each case. You can try to enforce a sort of schema by, for example, giving each node a Type property, but Neo4j will not enforce any sort of rules for you.

您需要使用HAS功能。

ExecutionResult result = engine.execute("START n=node(*) WHERE HAS(n.abc) AND n.abc = 'fkdjasflasdjlf' return n ");

You need to use the "has" keyword, such as

START m=node(*) WHERE has(m.name) AND m.name ='Micha' RETURN id(m), m.name;

As far as node types go, you just need to add a property to each node of type. The node is just a blank object, by typing them you can differentiate them and link various types together.

A good schema design we have used is a root node which has Subreference relationships to Type = 'Subreference' . Then we create nodes of Type = 'Person' which are connected to the Subreference nodes by an 'Instance' relationship. That way to any node there is always a roadmap where you only have to filter on a fraction of the nodes in your database.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM