There is no procedure with the name "apoc.refactor.mergeNodes"

Hello.
I'm using Apoc Procedures in my Java app. I'm interested into XML import and the function mergeNodes.
The first one works fine, but the problem is only on the second one: mergeNodes.
I know how to register APOC procedures, so here my code:

private static void registerApocProcedure(GraphDatabaseService graphDB) throws IllegalArgumentException {
    //Register APOC procedures
    Procedures procedures = ((GraphDatabaseAPI) graphDB).getDependencyResolver().resolveDependency(Procedures.class);
    List<Class<?>> apocProcedures = Arrays.asList(Xml.class, Merge.class, RefactorConfig.class, RefactorResult.class, RelationshipRefactorResult.class, NodeRefactorResult.class);
    apocProcedures.forEach((proc) -> {
        try {
            procedures.registerProcedure(proc);
        } catch (KernelException e) {
            throw new RuntimeException("Error registering "+proc,e);
        }
    });
}

As you can see I also included some procedures that recalls the name of apoc.refactor.mergeNodes, but when I run my app I got the error:

There is no procedure with the name apoc.refactor.mergeNodes registered for this database instance. Please ensure you've spelled the procedure name correctly and that the procedure is properly deployed.

It seems to me that I'm not using the right APOC procedure. If this is the problem, which is the right APOC procedure which implements the mergeNodes?
Thanks!

Looks like you're missing GraphRefactoring, see neo4j-apoc-procedures/GraphRefactoring.java at 3.4 · neo4j-contrib/neo4j-apoc-procedures · GitHub

On a different notice: if you're using apoc procedures from within your java code, you can directly instantiate the class implementing the apoc procedure like this (pseudo code)

GraphRefactoring graphRefactoring = new GraphRefactoring();
graphRefactoring.db = myGraphDb;
graphRefactoring.log = myLog;
graphRefactoring.mergeNodes(params)

This way you don't have to register anything.

1 Like

Thanks and sorry for late reply.
Is there a way to understand which class I need to load given the name?
For example, now I need to load the corresponding class of apoc.text.join.
Cheers.

You need to inspect APOC sources for this. In your example take a look in package apoc.text (neo4j-apoc-procedures/src/main/java/apoc/text at 3.4 · neo4j-contrib/neo4j-apoc-procedures · GitHub). Take a look at @Description annotations, for your example specifically neo4j-apoc-procedures/Strings.java at 3.4 · neo4j-contrib/neo4j-apoc-procedures · GitHub

I followed your suggestion and I tried with:

private static void registerApocProcedure(GraphDatabaseService graphDB) throws IllegalArgumentException {
		//Register APOC procedures
		Procedures procedures = ((GraphDatabaseAPI) graphDB).getDependencyResolver().resolveDependency(Procedures.class);
		List<Class<?>> apocProcedures = Arrays.asList(Xml.class, GraphRefactoring.class, apoc.text.Strings.class);
		apocProcedures.forEach((proc) -> {
			try {
				procedures.registerProcedure(proc);
			} catch (KernelException e) {
				throw new RuntimeException("Error registering "+proc,e);
			}
		});
	}

I added apoc.text.Strings.class, but it didn't work.
The only way to recover join is to call the function like this:

apoc.text.Strings joinFunction = new  Strings();
joinFunction.join(texts, delimiter);

there is only one problem: I already have a cypher query which uses apoc.text.join, and I do not know how to make it work together. Is there a solution for this?
Many thanks.

apoc.text.join is a function and not a procedure. Therefore you need to call procedures.registerFunction(proc) to register it.