From 7cf92a702d4f91751d4950c97e312088571e78ad Mon Sep 17 00:00:00 2001 From: Pontus Melke Date: Thu, 8 Jun 2017 11:30:03 +0200 Subject: [PATCH] Procedure for searching legacy index for relationships --- .../builtinprocs/BuiltInProcedures.java | 24 ++++++-- .../acceptance/LegacyIndexProcsIT.scala | 55 +++++++++++++++++++ 2 files changed, 75 insertions(+), 4 deletions(-) diff --git a/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/BuiltInProcedures.java b/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/BuiltInProcedures.java index b7674dd1d97d..0f34af6efa1d 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/BuiltInProcedures.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/BuiltInProcedures.java @@ -204,8 +204,8 @@ public Stream nodeLegacyIndexSeek( @Name( "indexName" ) String legac throw new ProcedureException( Status.LegacyIndex.LegacyIndexNotFound, "Node index %s not found", legacyIndexName ); } - IndexHits query = index.forNodes( legacyIndexName ).query( key, value ); - return query.stream().map( NodeResult::new ); + IndexHits nodes = index.forNodes( legacyIndexName ).query( key, value ); + return nodes.stream().map( NodeResult::new ); } @Description( "Search nodes from legacy index. Replaces `START n=node:nodes('key:foo*')`" ) @@ -237,8 +237,24 @@ public Stream relationshipLegacyIndexSeek( @Name( "indexName throw new ProcedureException( Status.LegacyIndex.LegacyIndexNotFound, "Node index %s not found", legacyIndexName ); } - IndexHits query = index.forRelationships( legacyIndexName ).query( key, value ); - return query.stream().map( RelationshipResult::new ); + IndexHits relationships = index.forRelationships( legacyIndexName ).query( key, value ); + return relationships.stream().map( RelationshipResult::new ); + } + + @Description( "Search relationship from legacy index. Replaces `START r=relationship:relIndex('key:foo*')`" ) + @Procedure( name = "db.relationshipLegacyIndexSearch", mode = SCHEMA ) + public Stream relationshipLegacyIndexSearch( @Name( "indexName" ) String legacyIndexName, + @Name("query") Object query ) + throws ProcedureException + { + IndexManager index = graphDatabaseAPI.index(); + if ( !index.existsForRelationships( legacyIndexName ) ) + { + throw new ProcedureException( Status.LegacyIndex.LegacyIndexNotFound, "Node index %s not found", + legacyIndexName ); + } + IndexHits relationships = index.forRelationships( legacyIndexName ).query( query ); + return relationships.stream().map( RelationshipResult::new ); } private IndexProcedures indexProcedures() diff --git a/enterprise/cypher/acceptance-spec-suite/src/test/scala/org/neo4j/internal/cypher/acceptance/LegacyIndexProcsIT.scala b/enterprise/cypher/acceptance-spec-suite/src/test/scala/org/neo4j/internal/cypher/acceptance/LegacyIndexProcsIT.scala index 0a6f8482e36f..c8af92256fa4 100644 --- a/enterprise/cypher/acceptance-spec-suite/src/test/scala/org/neo4j/internal/cypher/acceptance/LegacyIndexProcsIT.scala +++ b/enterprise/cypher/acceptance-spec-suite/src/test/scala/org/neo4j/internal/cypher/acceptance/LegacyIndexProcsIT.scala @@ -90,4 +90,59 @@ class LegacyIndexProcsIT extends ExecutionEngineFunSuite { a [CypherExecutionException] should be thrownBy execute("""CALL db.relationshipLegacyIndexSeek('index', 'key', 'value') YIELD relationship AS r RETURN r""") } + + test("Relationship legacy index search plus MATCH") { + val node = createNode(Map("prop" -> 42)) + val otherNode = createNode(Map("prop" -> 21)) + val relationship = relate(node, otherNode) + + graph.inTx { + val relationshipIndex = graph.index().forRelationships("relIndex") + relationshipIndex.add(relationship, "key", "value") + } + + val query = "CALL db.relationshipLegacyIndexSearch('relIndex','key:*') YIELD relationship AS r MATCH (a)-[r]-(b) RETURN r" + val result = execute(query) + + result.toList should equal(List( + Map("r"-> relationship), + Map("r"-> relationship) + )) + } + + test("Relationship legacy index search plus MATCH directed") { + val node = createNode(Map("prop" -> 42)) + val otherNode = createNode(Map("prop" -> 21)) + val relationship = relate(node, otherNode) + + graph.inTx { + val relationshipIndex = graph.index().forRelationships("relIndex") + relationshipIndex.add(relationship, "key", "value") + } + + val query = "CALL db.relationshipLegacyIndexSearch('relIndex','key:*') YIELD relationship AS r MATCH (a)-[r]->(b) RETURN r" + val result = execute(query) + + result.toList should equal(List( + Map("r"-> relationship) + )) + } + + test("should return correct results on combined node and relationship index starts") { + val node = createNode() + val resultNode = createNode() + val rel = relate(node, resultNode) + relate(node, createNode()) + + graph.inTx { + graph.index().forNodes("nodes").add(node, "key", "A") + graph.index().forRelationships("rels").add(rel, "key", "B") + } + + val result = execute("CALL db.nodeLegacyIndexSeek('nodes', 'key', 'A') YIELD node AS n " + + "CALL db.relationshipLegacyIndexSeek('rels', 'key', 'B') YIELD relationship AS r " + + "MATCH (n)-[r]->(b) RETURN b") + result.toList should equal(List(Map("b" -> resultNode))) + } + }