Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 3 additions & 25 deletions common/src/main/java/apoc/util/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@
import org.neo4j.graphdb.TransactionTerminatedException;
import org.neo4j.graphdb.schema.ConstraintType;
import org.neo4j.graphdb.schema.IndexDefinition;
import org.neo4j.graphdb.schema.IndexType;
import org.neo4j.graphdb.security.URLAccessChecker;
import org.neo4j.graphdb.security.URLAccessValidationError;
import org.neo4j.internal.kernel.api.procs.ProcedureCallContext;
Expand Down Expand Up @@ -1327,37 +1326,16 @@ public static int indexOf(List<Object> list, Object value) {
.orElse(-1);
}

/*
* Get all indexes from Neo4j
* Currently filters out vector indexes
* When vector indexes are supported, this can be changed to transaction.schema().getIndexes()
*/
public static Iterable<IndexDefinition> getIndexes(Transaction transaction) {
return StreamSupport.stream(transaction.schema().getIndexes().spliterator(), false)
.filter(indexDefinition -> indexDefinition.getIndexType() != IndexType.VECTOR)
.toList();
return transaction.schema().getIndexes();
}

/*
* Get all indexes from Neo4j for a given label
* Currently filters out vector indexes
* When vector indexes are supported, this can be changed to transaction.schema().getIndexes(label)
*/
public static Iterable<IndexDefinition> getIndexes(Transaction transaction, Label label) {
return StreamSupport.stream(transaction.schema().getIndexes(label).spliterator(), false)
.filter(indexDefinition -> indexDefinition.getIndexType() != IndexType.VECTOR)
.toList();
return transaction.schema().getIndexes(label);
}

/*
* Get all indexes from Neo4j for a given relationship type
* Currently filters out vector indexes
* When vector indexes are supported, this can be changed to transaction.schema().getIndexes(relType)
*/
public static Iterable<IndexDefinition> getIndexes(Transaction transaction, RelationshipType relType) {
return StreamSupport.stream(transaction.schema().getIndexes(relType).spliterator(), false)
.filter(indexDefinition -> indexDefinition.getIndexType() != IndexType.VECTOR)
.toList();
return transaction.schema().getIndexes(relType);
}

public static <T> T withBackOffRetries(Supplier<T> func, long initialTimeout, long upperTimeout, Log log) {
Expand Down
2 changes: 2 additions & 0 deletions core/src/main/java/apoc/schema/Schemas.java
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ public List<AssertSchemaResult> assertIndexes(

for (IndexDefinition definition : Util.getIndexes(tx)) {
if (definition.getIndexType() == IndexType.LOOKUP) continue;
// Don't drop vector indexes
if (definition.getIndexType() == IndexType.VECTOR) continue;
if (definition.isConstraintIndex()) continue;
if (definition.isMultiTokenIndex()) continue;

Expand Down
37 changes: 36 additions & 1 deletion core/src/test/java/apoc/meta/MetaTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ public class MetaTest {
"apoc.meta.graph.of",
"apoc.meta.graphSample",
"apoc.meta.subGraph"))
.withSetting(GraphDatabaseInternalSettings.cypher_enable_vector_type, true)
.withSetting(GraphDatabaseInternalSettings.latest_kernel_version, Byte.MAX_VALUE)
.withSetting(GraphDatabaseInternalSettings.latest_runtime_version, Integer.MAX_VALUE)
.withSetting(
Expand Down Expand Up @@ -541,6 +540,42 @@ public void testMetaGraph2() {
});
}

@Test
public void testVectorIndexes() {
db.executeTransactionally(
"""
CREATE VECTOR INDEX moviePlots IF NOT EXISTS
FOR (m:Movie)
ON m.embedding
OPTIONS { indexConfig: {
`vector.dimensions`: 1536,
`vector.similarity_function`: 'cosine'
}}
""");

db.executeTransactionally("CREATE (m:Movie {name:'The Movie', embedding: [1, 2, 3]})");

TestUtil.testResult(
db,
"""
CALL apoc.meta.data()
YIELD label, property, count, unique, index, existence, type, array, left, right, other, otherLabels, elementType
RETURN * ORDER BY elementType, property""",
(r) -> {
Map<String, Object> row = r.next();
assertEquals("node", row.get("elementType"));
assertEquals("embedding", row.get("property"));
assertEquals("Movie", row.get("label"));
assertEquals(true, row.get("index"));
row = r.next();
assertEquals("node", row.get("elementType"));
assertEquals("name", row.get("property"));
assertEquals("Movie", row.get("label"));
assertEquals(false, row.get("index"));
assertFalse(r.hasNext());
});
}

@Test
public void testMetaData() {
db.executeTransactionally("create index for (n:Movie) on (n.title)");
Expand Down
14 changes: 12 additions & 2 deletions core/src/test/java/apoc/periodic/PeriodicTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -947,7 +947,7 @@ public void testTruncate() {
createDatasetForTruncate();

TestUtil.testCallEmpty(db, "CALL apoc.periodic.truncate", Collections.emptyMap());
assertCountEntitiesAndIndexes(0, 0, 4, 2);
assertCountEntitiesAndIndexes(0, 0, 5, 2);

dropSchema();

Expand Down Expand Up @@ -1007,10 +1007,20 @@ private void createDatasetForTruncate() {
db.executeTransactionally("CREATE CONSTRAINT FOR (a:Two) REQUIRE a.surname IS UNIQUE");
db.executeTransactionally("CREATE INDEX FOR (n:Three) ON (n.other)");
db.executeTransactionally("CREATE CONSTRAINT FOR (a:Actor) REQUIRE a.name IS UNIQUE");
db.executeTransactionally(
"""
CREATE VECTOR INDEX moviePlots IF NOT EXISTS
FOR (m:Movie)
ON m.embedding
OPTIONS { indexConfig: {
`vector.dimensions`: 1536,
`vector.similarity_function`: 'cosine'
}}
""");

final int expectedNodes = iterations * 3;
final int expectedRels = iterations * 2;
assertCountEntitiesAndIndexes(expectedNodes, expectedRels, 4, 2);
assertCountEntitiesAndIndexes(expectedNodes, expectedRels, 5, 2);
}

private void assertCountEntitiesAndIndexes(
Expand Down
26 changes: 26 additions & 0 deletions core/src/test/java/apoc/schema/SchemasTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,32 @@ public void testDropIndexWhenUsingDropExisting() {
}
}

@Test
public void testDropIndexDoesntAffectVectorIndexes() {
db.executeTransactionally("CREATE INDEX FOR (n:Foo) ON (n.bar)");
db.executeTransactionally(
"""
CREATE VECTOR INDEX moviePlots IF NOT EXISTS
FOR (m:Movie)
ON m.embedding
OPTIONS { indexConfig: {
`vector.dimensions`: 1536,
`vector.similarity_function`: 'cosine'
}}
""");
testCall(db, "CALL apoc.schema.assert(null,null)", (r) -> {
assertEquals("Foo", r.get("label"));
assertEquals("bar", r.get("key"));
assertEquals(false, r.get("unique"));
assertEquals("DROPPED", r.get("action"));
});
try (Transaction tx = db.beginTx()) {
List<IndexDefinition> indexes = Iterables.asList(tx.schema().getIndexes());
// the multi-token idx remains
assertEquals(1, indexes.size());
}
}

@Test
public void testDropIndexAndCreateIndexWhenUsingDropExisting() {
db.executeTransactionally("CREATE INDEX FOR (n:Foo) ON (n.bar)");
Expand Down
1 change: 0 additions & 1 deletion core/src/test/java/apoc/util/UtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ public class UtilsTest {

@ClassRule
public static DbmsRule db = new ImpermanentDbmsRule()
.withSetting(GraphDatabaseInternalSettings.cypher_enable_vector_type, true)
.withSetting(GraphDatabaseInternalSettings.latest_kernel_version, Byte.MAX_VALUE)
.withSetting(GraphDatabaseInternalSettings.latest_runtime_version, Integer.MAX_VALUE);

Expand Down
Loading