I try to write a function in Java that finds nodes in my Neo4j graph database with same names and labels.
@UserFunction(value = "boris.example")
@Description("finds nodes with same name")
public ResourceIterator<Node> passName(@Name("nodeId") long nodeId)
{
Node nodeX = null;
Node node = db.getNodeById( nodeId ); //Find node with spcific ID
Object nameVal = node.getProperties("name"); //Get its name
Label label = Label.label("VersionableObject"); //Decl. of label
// Find nodes by label and name
ResourceIterator<Node> nodes = db.findNodes(label, "name", nameVal);
nodes.close();
return nodes;
}
This function causes following exception an refuses to start Neo4j:
"Argument ResourceIterator<Node>
at position 0 in passName
with
type Label
cannot be converted to a Neo4j type: Don't know how to map org.neo4j.graphdb.ResourceIterator
to the Neo4j Type System."
Then I tried to convert ResourceIterator to Stream using
Stream<Node> nodesStream = nodes.stream();
Same Error - Neo4j can't map Stream..
ResourceIterator<Node> nodes = db.findNodes(label, "name", nameVal);
while (nodes.hasNext()) {
nodeX = nodes.next();
}
nodes.close();
return nodeX;
Output in Neo4j empty, even though it should find 3 nodes.
Converting the Stream to Array or List did not work as well.
Finding one node and displaying itself or its properties works, e.g.:
Node node = db.getNodeById( nodeId );
Map<String, Object> propertyMap = node.getProperties("name");
EDIT
After changing @UserFunction to @Procedure with mode.READ:
package org.neo4j.example.procedure_template;
import org.neo4j.graphdb.ResourceIterator;
import java.util.stream.Stream;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Label;
import org.neo4j.graphdb.Node;
import org.neo4j.logging.Log;
import org.neo4j.procedure.*;
import org.neo4j.procedure.Description;
import org.neo4j.procedure.Name;
public class FindNode {
@Context
public GraphDatabaseService db;
@Context
public Log log;
public FindNode() {
}
@Procedure(value = "boris.getAllNodesWithProperty", mode = Mode.READ)
@Description("boris.getAllNodesWithProperty - finds Node by ID and return defined Property")
public Stream<Node> passName(@Name("nodeId") long nodeId)
{
Node node = db.getNodeById( nodeId );
Object nameVal = node.getProperties("name");
Label label = Label.label("VersionableObject");
ResourceIterator<Node> nodes = db.findNodes(label, "name", nameVal);
Stream<Node> nodesStream = nodes.stream();
return nodesStream;
}
}
In this case i get: "Procedures with zero output fields must be declared as VOID".
Any ideas? Thank you!