From ac6a27de184871ab424d52547ee180e42b7e9cae Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Tue, 27 Feb 2024 14:39:46 +0100 Subject: [PATCH 1/4] mdi --- .../java/com/arangodb/ArangoCollection.java | 13 ++ .../com/arangodb/ArangoCollectionAsync.java | 8 + .../java/com/arangodb/entity/IndexType.java | 2 + .../internal/ArangoCollectionAsyncImpl.java | 5 + .../internal/ArangoCollectionImpl.java | 5 + .../internal/InternalArangoCollection.java | 9 + .../com/arangodb/model/MDIndexOptions.java | 155 ++++++++++++++++++ .../com/arangodb/model/OptionsBuilder.java | 4 + .../com/arangodb/model/ZKDIndexOptions.java | 2 + .../arangodb/ArangoCollectionAsyncTest.java | 57 +++++++ .../com/arangodb/ArangoCollectionTest.java | 57 +++++++ 11 files changed, 317 insertions(+) create mode 100644 core/src/main/java/com/arangodb/model/MDIndexOptions.java diff --git a/core/src/main/java/com/arangodb/ArangoCollection.java b/core/src/main/java/com/arangodb/ArangoCollection.java index 302335607..408c7f3e0 100644 --- a/core/src/main/java/com/arangodb/ArangoCollection.java +++ b/core/src/main/java/com/arangodb/ArangoCollection.java @@ -665,9 +665,22 @@ MultiDocumentEntity> deleteDocuments( * @return information about the index * @see API Documentation * @since ArangoDB 3.9 + * @deprecated since ArangoDB 3.12, use {@link #ensureMDIndex(Iterable, MDIndexOptions)} instead. */ + @Deprecated IndexEntity ensureZKDIndex(Iterable fields, ZKDIndexOptions options); + /** + * Creates a multi-dimensional index for the collection, if it does not already exist. + * + * @param fields A list of attribute names used for each dimension + * @param options Additional options, can be null + * @return information about the index + * @see API Documentation + * @since ArangoDB 3.12 + */ + IndexEntity ensureMDIndex(Iterable fields, MDIndexOptions options); + /** * Creates an inverted index for the collection, if it does not already exist. * diff --git a/core/src/main/java/com/arangodb/ArangoCollectionAsync.java b/core/src/main/java/com/arangodb/ArangoCollectionAsync.java index f3dd03484..ca1399e96 100644 --- a/core/src/main/java/com/arangodb/ArangoCollectionAsync.java +++ b/core/src/main/java/com/arangodb/ArangoCollectionAsync.java @@ -305,9 +305,17 @@ CompletableFuture>> deleteDocume /** * Asynchronous version of {@link ArangoCollection#ensureZKDIndex(Iterable, ZKDIndexOptions)} + * + * @deprecated since ArangoDB 3.12, use {@link #ensureMDIndex(Iterable, MDIndexOptions)} instead. */ + @Deprecated CompletableFuture ensureZKDIndex(Iterable fields, ZKDIndexOptions options); + /** + * Asynchronous version of {@link ArangoCollection#ensureMDIndex(Iterable, MDIndexOptions)} + */ + CompletableFuture ensureMDIndex(Iterable fields, MDIndexOptions options); + /** * Asynchronous version of {@link ArangoCollection#ensureInvertedIndex(InvertedIndexOptions)} */ diff --git a/core/src/main/java/com/arangodb/entity/IndexType.java b/core/src/main/java/com/arangodb/entity/IndexType.java index d3303b5f5..cbd886fac 100644 --- a/core/src/main/java/com/arangodb/entity/IndexType.java +++ b/core/src/main/java/com/arangodb/entity/IndexType.java @@ -52,6 +52,8 @@ public enum IndexType { zkd, + mdi, + /** * @since ArangoDB 3.10 */ diff --git a/core/src/main/java/com/arangodb/internal/ArangoCollectionAsyncImpl.java b/core/src/main/java/com/arangodb/internal/ArangoCollectionAsyncImpl.java index a7b62fa74..ed1d3e8da 100644 --- a/core/src/main/java/com/arangodb/internal/ArangoCollectionAsyncImpl.java +++ b/core/src/main/java/com/arangodb/internal/ArangoCollectionAsyncImpl.java @@ -387,6 +387,11 @@ public CompletableFuture ensureZKDIndex(final Iterable fiel return executorAsync().execute(() -> createZKDIndexRequest(fields, options), IndexEntity.class); } + @Override + public CompletableFuture ensureMDIndex(final Iterable fields, final MDIndexOptions options) { + return executorAsync().execute(() -> createMDIndexRequest(fields, options), IndexEntity.class); + } + @Override public CompletableFuture> getIndexes() { return executorAsync().execute(this::getIndexesRequest, getIndexesResponseDeserializer()); diff --git a/core/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java b/core/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java index 56da41518..400508b06 100644 --- a/core/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java +++ b/core/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java @@ -378,6 +378,11 @@ public IndexEntity ensureZKDIndex(final Iterable fields, final ZKDIndexO return executorSync().execute(createZKDIndexRequest(fields, options), IndexEntity.class); } + @Override + public IndexEntity ensureMDIndex(final Iterable fields, final MDIndexOptions options) { + return executorSync().execute(createMDIndexRequest(fields, options), IndexEntity.class); + } + @Override public Collection getIndexes() { return executorSync().execute(getIndexesRequest(), getIndexesResponseDeserializer()); diff --git a/core/src/main/java/com/arangodb/internal/InternalArangoCollection.java b/core/src/main/java/com/arangodb/internal/InternalArangoCollection.java index 3d89ca5b5..ab3729c90 100644 --- a/core/src/main/java/com/arangodb/internal/InternalArangoCollection.java +++ b/core/src/main/java/com/arangodb/internal/InternalArangoCollection.java @@ -475,6 +475,15 @@ protected InternalRequest createZKDIndexRequest( return request; } + protected InternalRequest createMDIndexRequest( + final Iterable fields, final MDIndexOptions options) { + final InternalRequest request = request(dbName, RequestType.POST, PATH_API_INDEX); + request.putQueryParam(COLLECTION, name); + request.setBody(getSerde().serialize(OptionsBuilder.build(options != null ? options : + new MDIndexOptions().fieldValueTypes(MDIndexOptions.FieldValueTypes.DOUBLE), fields))); + return request; + } + protected InternalRequest getIndexesRequest() { final InternalRequest request = request(dbName, RequestType.GET, PATH_API_INDEX); request.putQueryParam(COLLECTION, name); diff --git a/core/src/main/java/com/arangodb/model/MDIndexOptions.java b/core/src/main/java/com/arangodb/model/MDIndexOptions.java new file mode 100644 index 000000000..5ac62a4a7 --- /dev/null +++ b/core/src/main/java/com/arangodb/model/MDIndexOptions.java @@ -0,0 +1,155 @@ +/* + * DISCLAIMER + * + * Copyright 2016 ArangoDB GmbH, Cologne, Germany + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright holder is ArangoDB GmbH, Cologne, Germany + */ + +package com.arangodb.model; + +import com.arangodb.entity.IndexType; +import com.fasterxml.jackson.annotation.JsonProperty; + + +/** + * @author Michele Rastelli + * @see API Documentation + * @since ArangoDB 3.12 + */ +public final class MDIndexOptions extends IndexOptions { + + final IndexType type = IndexType.mdi; + private Iterable fields; + private Boolean unique; + private FieldValueTypes fieldValueTypes; + private Boolean estimates; + private Boolean sparse; + private Iterable storedValues; + + + public MDIndexOptions() { + super(); + } + + @Override + MDIndexOptions getThis() { + return this; + } + + public Iterable getFields() { + return fields; + } + + /** + * @param fields A list of attribute names used for each dimension. Array expansions are not allowed. + * @return options + */ + MDIndexOptions fields(final Iterable fields) { + this.fields = fields; + return this; + } + + public IndexType getType() { + return type; + } + + public Boolean getUnique() { + return unique; + } + + /** + * @param unique if true, then create a unique index + * @return options + */ + public MDIndexOptions unique(final Boolean unique) { + this.unique = unique; + return this; + } + + public FieldValueTypes getFieldValueTypes() { + return fieldValueTypes; + } + + /** + * @param fieldValueTypes must be {@link FieldValueTypes#DOUBLE}, currently only doubles are supported as values. + * @return options + */ + public MDIndexOptions fieldValueTypes(final FieldValueTypes fieldValueTypes) { + this.fieldValueTypes = fieldValueTypes; + return this; + } + + public Boolean getEstimates() { + return estimates; + } + + /** + * @param estimates controls whether index selectivity estimates are maintained for the index. Not maintaining index + * selectivity estimates can have a slightly positive impact on write performance. + * The downside of turning off index selectivity estimates is that the query optimizer is not able + * to determine the usefulness of different competing indexes in AQL queries when there are + * multiple candidate indexes to choose from. + * The estimates attribute is optional and defaults to true if not set. + * It cannot be disabled for non-unique multi-dimensional indexes because they have a fixed + * selectivity estimate of 1. + * @return options + */ + public MDIndexOptions estimates(final Boolean estimates) { + this.estimates = estimates; + return this; + } + + public Boolean getSparse() { + return sparse; + } + + /** + * @param sparse if true, then create a sparse index + * @return options + */ + public MDIndexOptions sparse(final Boolean sparse) { + this.sparse = sparse; + return this; + } + + public Iterable getStoredValues() { + return storedValues; + } + + /** + * @param storedValues can contain an array of paths to additional attributes to store in the index. + * These additional attributes cannot be used for index lookups or for sorting, but they can be + * used for projections. This allows an index to fully cover more queries and avoid extra + * document lookups. + * You can have the same attributes in storedValues and fields as the attributes in fields + * cannot be used for projections, but you can also store additional attributes that are not + * listed in fields. + * Attributes in storedValues cannot overlap with the attributes specified in prefixFields. + * Non-existing attributes are stored as null values inside storedValues. + * The maximum number of attributes in storedValues is 32. + * @return options + */ + public MDIndexOptions storedValues(final Iterable storedValues) { + this.storedValues = storedValues; + return this; + } + + public enum FieldValueTypes { + @JsonProperty("double") + DOUBLE + } + +} diff --git a/core/src/main/java/com/arangodb/model/OptionsBuilder.java b/core/src/main/java/com/arangodb/model/OptionsBuilder.java index 216d9b6e4..03b72e5e0 100644 --- a/core/src/main/java/com/arangodb/model/OptionsBuilder.java +++ b/core/src/main/java/com/arangodb/model/OptionsBuilder.java @@ -62,6 +62,10 @@ public static ZKDIndexOptions build(final ZKDIndexOptions options, final Iterabl return options.fields(fields); } + public static MDIndexOptions build(final MDIndexOptions options, final Iterable fields) { + return options.fields(fields); + } + public static CollectionCreateOptions build(final CollectionCreateOptions options, final String name) { return options.name(name); } diff --git a/core/src/main/java/com/arangodb/model/ZKDIndexOptions.java b/core/src/main/java/com/arangodb/model/ZKDIndexOptions.java index e4742e8ed..b5d9041b9 100644 --- a/core/src/main/java/com/arangodb/model/ZKDIndexOptions.java +++ b/core/src/main/java/com/arangodb/model/ZKDIndexOptions.java @@ -27,7 +27,9 @@ * @author Michele Rastelli * @see API Documentation * @since ArangoDB 3.9 + * @deprecated since ArangoDB 3.12, use {@link MDIndexOptions} instead. */ +@Deprecated public final class ZKDIndexOptions extends IndexOptions { final IndexType type = IndexType.zkd; diff --git a/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java b/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java index e2c3ca18d..9928ad73c 100644 --- a/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java +++ b/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java @@ -1615,6 +1615,63 @@ void createZKDIndexWithOptions(ArangoCollectionAsync collection) throws Executio collection.deleteIndex(indexResult.getId()).get(); } + @ParameterizedTest + @MethodSource("asyncCols") + void createMDIndex(ArangoCollectionAsync collection) throws ExecutionException, InterruptedException { + assumeTrue(isAtLeastVersion(3, 12)); + collection.truncate().get(); + + String f1 = "field-" + rnd(); + String f2 = "field-" + rnd(); + + final IndexEntity indexResult = collection.ensureMDIndex(Arrays.asList(f1, f2), null).get(); + assertThat(indexResult).isNotNull(); + assertThat(indexResult.getConstraint()).isNull(); + assertThat(indexResult.getFields()).contains(f1); + assertThat(indexResult.getFields()).contains(f2); + assertThat(indexResult.getId()).startsWith(COLLECTION_NAME); + assertThat(indexResult.getIsNewlyCreated()).isTrue(); + assertThat(indexResult.getMinLength()).isNull(); + assertThat(indexResult.getType()).isEqualTo(IndexType.mdi); + assertThat(indexResult.getUnique()).isFalse(); + collection.deleteIndex(indexResult.getId()).get(); + } + + @ParameterizedTest + @MethodSource("asyncCols") + void createMDIndexWithOptions(ArangoCollectionAsync collection) throws ExecutionException, InterruptedException { + assumeTrue(isAtLeastVersion(3, 12)); + collection.truncate().get(); + + String name = "MDIndex-" + rnd(); + final MDIndexOptions options = new MDIndexOptions() + .name(name) + .unique(false) + .fieldValueTypes(MDIndexOptions.FieldValueTypes.DOUBLE) + .estimates(false) + .sparse(true) + .storedValues(Arrays.asList("v1", "v2")); + + String f1 = "field-" + rnd(); + String f2 = "field-" + rnd(); + + final IndexEntity indexResult = collection.ensureMDIndex(Arrays.asList(f1, f2), options).get(); + assertThat(indexResult.getType()).isEqualTo(IndexType.mdi); + assertThat(indexResult.getId()).startsWith(COLLECTION_NAME); + assertThat(indexResult.getName()).isEqualTo(name); + assertThat(indexResult.getUnique()).isFalse(); + assertThat(indexResult.getEstimates()).isFalse(); + assertThat(indexResult.getSparse()).isTrue(); + assertThat(indexResult.getStoredValues()) + .hasSize(2) + .contains("v1", "v2"); + assertThat(indexResult.getFields()) + .contains(f1) + .contains(f2); + assertThat(indexResult.getIsNewlyCreated()).isTrue(); + collection.deleteIndex(indexResult.getId()).get(); + } + @ParameterizedTest @MethodSource("asyncCols") void indexEstimates(ArangoCollectionAsync collection) throws ExecutionException, InterruptedException { diff --git a/driver/src/test/java/com/arangodb/ArangoCollectionTest.java b/driver/src/test/java/com/arangodb/ArangoCollectionTest.java index 8d1087992..cfaeb0310 100644 --- a/driver/src/test/java/com/arangodb/ArangoCollectionTest.java +++ b/driver/src/test/java/com/arangodb/ArangoCollectionTest.java @@ -1640,6 +1640,63 @@ void createZKDIndexWithOptions(ArangoCollection collection) { collection.deleteIndex(indexResult.getId()); } + @ParameterizedTest + @MethodSource("cols") + void createMDIndex(ArangoCollection collection) { + assumeTrue(isAtLeastVersion(3, 12)); + collection.truncate(); + + String f1 = "field-" + rnd(); + String f2 = "field-" + rnd(); + + final IndexEntity indexResult = collection.ensureMDIndex(Arrays.asList(f1, f2), null); + assertThat(indexResult).isNotNull(); + assertThat(indexResult.getConstraint()).isNull(); + assertThat(indexResult.getFields()).contains(f1); + assertThat(indexResult.getFields()).contains(f2); + assertThat(indexResult.getId()).startsWith(COLLECTION_NAME); + assertThat(indexResult.getIsNewlyCreated()).isTrue(); + assertThat(indexResult.getMinLength()).isNull(); + assertThat(indexResult.getType()).isEqualTo(IndexType.mdi); + assertThat(indexResult.getUnique()).isFalse(); + collection.deleteIndex(indexResult.getId()); + } + + @ParameterizedTest + @MethodSource("cols") + void createMDIndexWithOptions(ArangoCollection collection) { + assumeTrue(isAtLeastVersion(3, 12)); + collection.truncate(); + + String name = "MDIndex-" + rnd(); + final MDIndexOptions options = new MDIndexOptions() + .name(name) + .unique(false) + .fieldValueTypes(MDIndexOptions.FieldValueTypes.DOUBLE) + .estimates(false) + .sparse(true) + .storedValues(Arrays.asList("v1", "v2")); + + String f1 = "field-" + rnd(); + String f2 = "field-" + rnd(); + + final IndexEntity indexResult = collection.ensureMDIndex(Arrays.asList(f1, f2), options); + assertThat(indexResult.getType()).isEqualTo(IndexType.mdi); + assertThat(indexResult.getId()).startsWith(COLLECTION_NAME); + assertThat(indexResult.getName()).isEqualTo(name); + assertThat(indexResult.getUnique()).isFalse(); + assertThat(indexResult.getEstimates()).isFalse(); + assertThat(indexResult.getSparse()).isTrue(); + assertThat(indexResult.getStoredValues()) + .hasSize(2) + .contains("v1", "v2"); + assertThat(indexResult.getFields()) + .contains(f1) + .contains(f2); + assertThat(indexResult.getIsNewlyCreated()).isTrue(); + collection.deleteIndex(indexResult.getId()); + } + @ParameterizedTest @MethodSource("cols") void indexEstimates(ArangoCollection collection) { From 72aa32275ac01bb304d40d0b62b207f2b367cf4d Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Tue, 27 Feb 2024 15:56:36 +0100 Subject: [PATCH 2/4] mdi prefixed --- .../java/com/arangodb/ArangoCollection.java | 14 +- .../com/arangodb/ArangoCollectionAsync.java | 4 +- .../java/com/arangodb/entity/IndexType.java | 15 ++ .../internal/ArangoCollectionAsyncImpl.java | 2 +- .../internal/ArangoCollectionImpl.java | 2 +- .../internal/InternalArangoCollection.java | 6 +- .../model/AbstractMDIndexOptions.java | 143 ++++++++++++++++++ .../arangodb/model/MDIFieldValueTypes.java | 8 + .../com/arangodb/model/MDIndexOptions.java | 116 +------------- .../model/MDPrefixedIndexOptions.java | 62 ++++++++ .../com/arangodb/model/OptionsBuilder.java | 2 +- .../arangodb/ArangoCollectionAsyncTest.java | 38 ++++- .../com/arangodb/ArangoCollectionTest.java | 38 ++++- 13 files changed, 324 insertions(+), 126 deletions(-) create mode 100644 core/src/main/java/com/arangodb/model/AbstractMDIndexOptions.java create mode 100644 core/src/main/java/com/arangodb/model/MDIFieldValueTypes.java create mode 100644 core/src/main/java/com/arangodb/model/MDPrefixedIndexOptions.java diff --git a/core/src/main/java/com/arangodb/ArangoCollection.java b/core/src/main/java/com/arangodb/ArangoCollection.java index 408c7f3e0..4362502aa 100644 --- a/core/src/main/java/com/arangodb/ArangoCollection.java +++ b/core/src/main/java/com/arangodb/ArangoCollection.java @@ -665,21 +665,27 @@ MultiDocumentEntity> deleteDocuments( * @return information about the index * @see API Documentation * @since ArangoDB 3.9 - * @deprecated since ArangoDB 3.12, use {@link #ensureMDIndex(Iterable, MDIndexOptions)} instead. + * @deprecated since ArangoDB 3.12, use {@link #ensureMDIndex(Iterable, AbstractMDIndexOptions)} instead. */ @Deprecated IndexEntity ensureZKDIndex(Iterable fields, ZKDIndexOptions options); /** - * Creates a multi-dimensional index for the collection, if it does not already exist. + * Creates a multi-dimensional (prefixed) index for the collection, if it does not already exist. * * @param fields A list of attribute names used for each dimension - * @param options Additional options, can be null + * @param options Additional options, can be null. + * Can be an instance of: + *
    + *
  • {@link MDIndexOptions} to create a multi-dimensional index
  • + *
  • {@link MDPrefixedIndexOptions} to create a multi-dimensional prefixed index
  • + *
+ * * @return information about the index * @see API Documentation * @since ArangoDB 3.12 */ - IndexEntity ensureMDIndex(Iterable fields, MDIndexOptions options); + IndexEntity ensureMDIndex(Iterable fields, AbstractMDIndexOptions options); /** * Creates an inverted index for the collection, if it does not already exist. diff --git a/core/src/main/java/com/arangodb/ArangoCollectionAsync.java b/core/src/main/java/com/arangodb/ArangoCollectionAsync.java index ca1399e96..a753adc23 100644 --- a/core/src/main/java/com/arangodb/ArangoCollectionAsync.java +++ b/core/src/main/java/com/arangodb/ArangoCollectionAsync.java @@ -312,9 +312,9 @@ CompletableFuture>> deleteDocume CompletableFuture ensureZKDIndex(Iterable fields, ZKDIndexOptions options); /** - * Asynchronous version of {@link ArangoCollection#ensureMDIndex(Iterable, MDIndexOptions)} + * Asynchronous version of {@link ArangoCollection#ensureMDIndex(Iterable, AbstractMDIndexOptions)} */ - CompletableFuture ensureMDIndex(Iterable fields, MDIndexOptions options); + CompletableFuture ensureMDIndex(Iterable fields, AbstractMDIndexOptions options); /** * Asynchronous version of {@link ArangoCollection#ensureInvertedIndex(InvertedIndexOptions)} diff --git a/core/src/main/java/com/arangodb/entity/IndexType.java b/core/src/main/java/com/arangodb/entity/IndexType.java index cbd886fac..922a6c865 100644 --- a/core/src/main/java/com/arangodb/entity/IndexType.java +++ b/core/src/main/java/com/arangodb/entity/IndexType.java @@ -20,6 +20,8 @@ package com.arangodb.entity; +import com.fasterxml.jackson.annotation.JsonProperty; + /** * @author Mark Vollmary * @author Heiko Kernbach @@ -52,8 +54,21 @@ public enum IndexType { zkd, + /** + * Multi Dimensional Index + * @see Ref Doc + * @since ArangoDB 3.12 + */ mdi, + /** + * Multi Dimensional Prefixed Index + * @see Ref Doc + * @since ArangoDB 3.12 + */ + @JsonProperty("mdi-prefixed") + mdiPrefixed, + /** * @since ArangoDB 3.10 */ diff --git a/core/src/main/java/com/arangodb/internal/ArangoCollectionAsyncImpl.java b/core/src/main/java/com/arangodb/internal/ArangoCollectionAsyncImpl.java index ed1d3e8da..32c82706b 100644 --- a/core/src/main/java/com/arangodb/internal/ArangoCollectionAsyncImpl.java +++ b/core/src/main/java/com/arangodb/internal/ArangoCollectionAsyncImpl.java @@ -388,7 +388,7 @@ public CompletableFuture ensureZKDIndex(final Iterable fiel } @Override - public CompletableFuture ensureMDIndex(final Iterable fields, final MDIndexOptions options) { + public CompletableFuture ensureMDIndex(final Iterable fields, final AbstractMDIndexOptions options) { return executorAsync().execute(() -> createMDIndexRequest(fields, options), IndexEntity.class); } diff --git a/core/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java b/core/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java index 400508b06..98788d13e 100644 --- a/core/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java +++ b/core/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java @@ -379,7 +379,7 @@ public IndexEntity ensureZKDIndex(final Iterable fields, final ZKDIndexO } @Override - public IndexEntity ensureMDIndex(final Iterable fields, final MDIndexOptions options) { + public IndexEntity ensureMDIndex(final Iterable fields, final AbstractMDIndexOptions options) { return executorSync().execute(createMDIndexRequest(fields, options), IndexEntity.class); } diff --git a/core/src/main/java/com/arangodb/internal/InternalArangoCollection.java b/core/src/main/java/com/arangodb/internal/InternalArangoCollection.java index ab3729c90..ba43bb207 100644 --- a/core/src/main/java/com/arangodb/internal/InternalArangoCollection.java +++ b/core/src/main/java/com/arangodb/internal/InternalArangoCollection.java @@ -476,11 +476,11 @@ protected InternalRequest createZKDIndexRequest( } protected InternalRequest createMDIndexRequest( - final Iterable fields, final MDIndexOptions options) { + final Iterable fields, final AbstractMDIndexOptions options) { final InternalRequest request = request(dbName, RequestType.POST, PATH_API_INDEX); request.putQueryParam(COLLECTION, name); - request.setBody(getSerde().serialize(OptionsBuilder.build(options != null ? options : - new MDIndexOptions().fieldValueTypes(MDIndexOptions.FieldValueTypes.DOUBLE), fields))); + AbstractMDIndexOptions opts = options != null ? options : new MDIndexOptions().fieldValueTypes(MDIFieldValueTypes.DOUBLE); + request.setBody(getSerde().serialize(OptionsBuilder.build(opts, fields))); return request; } diff --git a/core/src/main/java/com/arangodb/model/AbstractMDIndexOptions.java b/core/src/main/java/com/arangodb/model/AbstractMDIndexOptions.java new file mode 100644 index 000000000..93d379c2f --- /dev/null +++ b/core/src/main/java/com/arangodb/model/AbstractMDIndexOptions.java @@ -0,0 +1,143 @@ +/* + * DISCLAIMER + * + * Copyright 2016 ArangoDB GmbH, Cologne, Germany + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright holder is ArangoDB GmbH, Cologne, Germany + */ + +package com.arangodb.model; + +import com.arangodb.arch.NoRawTypesInspection; +import com.arangodb.entity.IndexType; + + +/** + * @author Michele Rastelli + * @see API Documentation + * @since ArangoDB 3.12 + */ +@NoRawTypesInspection +public abstract class AbstractMDIndexOptions> extends IndexOptions { + + private Iterable fields; + private Boolean unique; + private MDIFieldValueTypes fieldValueTypes; + private Boolean estimates; + private Boolean sparse; + private Iterable storedValues; + + + public AbstractMDIndexOptions() { + super(); + } + + public abstract IndexType getType(); + + public Iterable getFields() { + return fields; + } + + /** + * @param fields A list of attribute names used for each dimension. Array expansions are not allowed. + * @return options + */ + T fields(final Iterable fields) { + this.fields = fields; + return getThis(); + } + + public Boolean getUnique() { + return unique; + } + + /** + * @param unique if true, then create a unique index + * @return options + */ + public T unique(final Boolean unique) { + this.unique = unique; + return getThis(); + } + + public MDIFieldValueTypes getFieldValueTypes() { + return fieldValueTypes; + } + + /** + * @param fieldValueTypes must be {@link MDIFieldValueTypes#DOUBLE}, currently only doubles are supported as values. + * @return options + */ + public T fieldValueTypes(final MDIFieldValueTypes fieldValueTypes) { + this.fieldValueTypes = fieldValueTypes; + return getThis(); + } + + public Boolean getEstimates() { + return estimates; + } + + /** + * @param estimates controls whether index selectivity estimates are maintained for the index. Not maintaining index + * selectivity estimates can have a slightly positive impact on write performance. + * The downside of turning off index selectivity estimates is that the query optimizer is not able + * to determine the usefulness of different competing indexes in AQL queries when there are + * multiple candidate indexes to choose from. + * The estimates attribute is optional and defaults to true if not set. + * It cannot be disabled for non-unique multi-dimensional indexes because they have a fixed + * selectivity estimate of 1. + * @return options + */ + public T estimates(final Boolean estimates) { + this.estimates = estimates; + return getThis(); + } + + public Boolean getSparse() { + return sparse; + } + + /** + * @param sparse if true, then create a sparse index + * @return options + */ + public T sparse(final Boolean sparse) { + this.sparse = sparse; + return getThis(); + } + + public Iterable getStoredValues() { + return storedValues; + } + + /** + * @param storedValues can contain an array of paths to additional attributes to store in the index. + * These additional attributes cannot be used for index lookups or for sorting, but they can be + * used for projections. This allows an index to fully cover more queries and avoid extra + * document lookups. + * You can have the same attributes in storedValues and fields as the attributes in fields + * cannot be used for projections, but you can also store additional attributes that are not + * listed in fields. + * Attributes in storedValues cannot overlap with the attributes specified in prefixFields. + * Non-existing attributes are stored as null values inside storedValues. + * The maximum number of attributes in storedValues is 32. + * @return options + */ + public T storedValues(final Iterable storedValues) { + this.storedValues = storedValues; + return getThis(); + } + +} diff --git a/core/src/main/java/com/arangodb/model/MDIFieldValueTypes.java b/core/src/main/java/com/arangodb/model/MDIFieldValueTypes.java new file mode 100644 index 000000000..1bf3fcb10 --- /dev/null +++ b/core/src/main/java/com/arangodb/model/MDIFieldValueTypes.java @@ -0,0 +1,8 @@ +package com.arangodb.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public enum MDIFieldValueTypes { + @JsonProperty("double") + DOUBLE +} diff --git a/core/src/main/java/com/arangodb/model/MDIndexOptions.java b/core/src/main/java/com/arangodb/model/MDIndexOptions.java index 5ac62a4a7..4ba8d5242 100644 --- a/core/src/main/java/com/arangodb/model/MDIndexOptions.java +++ b/core/src/main/java/com/arangodb/model/MDIndexOptions.java @@ -21,7 +21,6 @@ package com.arangodb.model; import com.arangodb.entity.IndexType; -import com.fasterxml.jackson.annotation.JsonProperty; /** @@ -29,127 +28,20 @@ * @see API Documentation * @since ArangoDB 3.12 */ -public final class MDIndexOptions extends IndexOptions { - - final IndexType type = IndexType.mdi; - private Iterable fields; - private Boolean unique; - private FieldValueTypes fieldValueTypes; - private Boolean estimates; - private Boolean sparse; - private Iterable storedValues; - +public final class MDIndexOptions extends AbstractMDIndexOptions { public MDIndexOptions() { super(); } @Override - MDIndexOptions getThis() { - return this; - } - - public Iterable getFields() { - return fields; - } - - /** - * @param fields A list of attribute names used for each dimension. Array expansions are not allowed. - * @return options - */ - MDIndexOptions fields(final Iterable fields) { - this.fields = fields; - return this; - } - public IndexType getType() { - return type; - } - - public Boolean getUnique() { - return unique; + return IndexType.mdi; } - /** - * @param unique if true, then create a unique index - * @return options - */ - public MDIndexOptions unique(final Boolean unique) { - this.unique = unique; - return this; - } - - public FieldValueTypes getFieldValueTypes() { - return fieldValueTypes; - } - - /** - * @param fieldValueTypes must be {@link FieldValueTypes#DOUBLE}, currently only doubles are supported as values. - * @return options - */ - public MDIndexOptions fieldValueTypes(final FieldValueTypes fieldValueTypes) { - this.fieldValueTypes = fieldValueTypes; - return this; - } - - public Boolean getEstimates() { - return estimates; - } - - /** - * @param estimates controls whether index selectivity estimates are maintained for the index. Not maintaining index - * selectivity estimates can have a slightly positive impact on write performance. - * The downside of turning off index selectivity estimates is that the query optimizer is not able - * to determine the usefulness of different competing indexes in AQL queries when there are - * multiple candidate indexes to choose from. - * The estimates attribute is optional and defaults to true if not set. - * It cannot be disabled for non-unique multi-dimensional indexes because they have a fixed - * selectivity estimate of 1. - * @return options - */ - public MDIndexOptions estimates(final Boolean estimates) { - this.estimates = estimates; - return this; - } - - public Boolean getSparse() { - return sparse; - } - - /** - * @param sparse if true, then create a sparse index - * @return options - */ - public MDIndexOptions sparse(final Boolean sparse) { - this.sparse = sparse; - return this; - } - - public Iterable getStoredValues() { - return storedValues; - } - - /** - * @param storedValues can contain an array of paths to additional attributes to store in the index. - * These additional attributes cannot be used for index lookups or for sorting, but they can be - * used for projections. This allows an index to fully cover more queries and avoid extra - * document lookups. - * You can have the same attributes in storedValues and fields as the attributes in fields - * cannot be used for projections, but you can also store additional attributes that are not - * listed in fields. - * Attributes in storedValues cannot overlap with the attributes specified in prefixFields. - * Non-existing attributes are stored as null values inside storedValues. - * The maximum number of attributes in storedValues is 32. - * @return options - */ - public MDIndexOptions storedValues(final Iterable storedValues) { - this.storedValues = storedValues; + @Override + MDIndexOptions getThis() { return this; } - public enum FieldValueTypes { - @JsonProperty("double") - DOUBLE - } - } diff --git a/core/src/main/java/com/arangodb/model/MDPrefixedIndexOptions.java b/core/src/main/java/com/arangodb/model/MDPrefixedIndexOptions.java new file mode 100644 index 000000000..76f040a1a --- /dev/null +++ b/core/src/main/java/com/arangodb/model/MDPrefixedIndexOptions.java @@ -0,0 +1,62 @@ +/* + * DISCLAIMER + * + * Copyright 2016 ArangoDB GmbH, Cologne, Germany + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright holder is ArangoDB GmbH, Cologne, Germany + */ + +package com.arangodb.model; + +import com.arangodb.entity.IndexType; + + +/** + * @author Michele Rastelli + * @see API Documentation + * @since ArangoDB 3.12 + */ +public final class MDPrefixedIndexOptions extends AbstractMDIndexOptions { + + private Iterable prefixFields; + + public MDPrefixedIndexOptions() { + super(); + } + + public Iterable getPrefixFields() { + return prefixFields; + } + + /** + * @param prefixFields An array of attribute names used as search prefix. Array expansions are not allowed. + * @return options + */ + public MDPrefixedIndexOptions prefixFields(final Iterable prefixFields) { + this.prefixFields = prefixFields; + return this; + } + + @Override + public IndexType getType() { + return IndexType.mdiPrefixed; + } + + @Override + MDPrefixedIndexOptions getThis() { + return this; + } + +} diff --git a/core/src/main/java/com/arangodb/model/OptionsBuilder.java b/core/src/main/java/com/arangodb/model/OptionsBuilder.java index 03b72e5e0..11ea5b0ab 100644 --- a/core/src/main/java/com/arangodb/model/OptionsBuilder.java +++ b/core/src/main/java/com/arangodb/model/OptionsBuilder.java @@ -62,7 +62,7 @@ public static ZKDIndexOptions build(final ZKDIndexOptions options, final Iterabl return options.fields(fields); } - public static MDIndexOptions build(final MDIndexOptions options, final Iterable fields) { + public static AbstractMDIndexOptions build(final AbstractMDIndexOptions options, final Iterable fields) { return options.fields(fields); } diff --git a/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java b/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java index 9928ad73c..41d1d68a3 100644 --- a/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java +++ b/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java @@ -1647,7 +1647,7 @@ void createMDIndexWithOptions(ArangoCollectionAsync collection) throws Execution final MDIndexOptions options = new MDIndexOptions() .name(name) .unique(false) - .fieldValueTypes(MDIndexOptions.FieldValueTypes.DOUBLE) + .fieldValueTypes(MDIFieldValueTypes.DOUBLE) .estimates(false) .sparse(true) .storedValues(Arrays.asList("v1", "v2")); @@ -1672,6 +1672,42 @@ void createMDIndexWithOptions(ArangoCollectionAsync collection) throws Execution collection.deleteIndex(indexResult.getId()).get(); } + @ParameterizedTest + @MethodSource("asyncCols") + void createMDPrefixedIndexWithOptions(ArangoCollectionAsync collection) throws ExecutionException, InterruptedException { + assumeTrue(isAtLeastVersion(3, 12)); + collection.truncate().get(); + + String name = "MDPrefixedIndex-" + rnd(); + final MDPrefixedIndexOptions options = new MDPrefixedIndexOptions() + .name(name) + .unique(false) + .fieldValueTypes(MDIFieldValueTypes.DOUBLE) + .estimates(false) + .sparse(true) + .storedValues(Arrays.asList("v1", "v2")) + .prefixFields(Arrays.asList("p1", "p2")); + + String f1 = "field-" + rnd(); + String f2 = "field-" + rnd(); + + final IndexEntity indexResult = collection.ensureMDIndex(Arrays.asList(f1, f2), options).get(); + assertThat(indexResult.getType()).isEqualTo(IndexType.mdiPrefixed); + assertThat(indexResult.getId()).startsWith(COLLECTION_NAME); + assertThat(indexResult.getName()).isEqualTo(name); + assertThat(indexResult.getUnique()).isFalse(); + assertThat(indexResult.getEstimates()).isFalse(); + assertThat(indexResult.getSparse()).isTrue(); + assertThat(indexResult.getStoredValues()) + .hasSize(2) + .contains("v1", "v2"); + assertThat(indexResult.getFields()) + .contains(f1) + .contains(f2); + assertThat(indexResult.getIsNewlyCreated()).isTrue(); + collection.deleteIndex(indexResult.getId()).get(); + } + @ParameterizedTest @MethodSource("asyncCols") void indexEstimates(ArangoCollectionAsync collection) throws ExecutionException, InterruptedException { diff --git a/driver/src/test/java/com/arangodb/ArangoCollectionTest.java b/driver/src/test/java/com/arangodb/ArangoCollectionTest.java index cfaeb0310..aae1715d7 100644 --- a/driver/src/test/java/com/arangodb/ArangoCollectionTest.java +++ b/driver/src/test/java/com/arangodb/ArangoCollectionTest.java @@ -1672,7 +1672,7 @@ void createMDIndexWithOptions(ArangoCollection collection) { final MDIndexOptions options = new MDIndexOptions() .name(name) .unique(false) - .fieldValueTypes(MDIndexOptions.FieldValueTypes.DOUBLE) + .fieldValueTypes(MDIFieldValueTypes.DOUBLE) .estimates(false) .sparse(true) .storedValues(Arrays.asList("v1", "v2")); @@ -1697,6 +1697,42 @@ void createMDIndexWithOptions(ArangoCollection collection) { collection.deleteIndex(indexResult.getId()); } + @ParameterizedTest + @MethodSource("cols") + void createMDPrefixedIndexWithOptions(ArangoCollection collection) { + assumeTrue(isAtLeastVersion(3, 12)); + collection.truncate(); + + String name = "MDPrefixedIndex-" + rnd(); + final MDPrefixedIndexOptions options = new MDPrefixedIndexOptions() + .name(name) + .unique(false) + .fieldValueTypes(MDIFieldValueTypes.DOUBLE) + .estimates(false) + .sparse(true) + .storedValues(Arrays.asList("v1", "v2")) + .prefixFields(Arrays.asList("p1", "p2")); + + String f1 = "field-" + rnd(); + String f2 = "field-" + rnd(); + + final IndexEntity indexResult = collection.ensureMDIndex(Arrays.asList(f1, f2), options); + assertThat(indexResult.getType()).isEqualTo(IndexType.mdiPrefixed); + assertThat(indexResult.getId()).startsWith(COLLECTION_NAME); + assertThat(indexResult.getName()).isEqualTo(name); + assertThat(indexResult.getUnique()).isFalse(); + assertThat(indexResult.getEstimates()).isFalse(); + assertThat(indexResult.getSparse()).isTrue(); + assertThat(indexResult.getStoredValues()) + .hasSize(2) + .contains("v1", "v2"); + assertThat(indexResult.getFields()) + .contains(f1) + .contains(f2); + assertThat(indexResult.getIsNewlyCreated()).isTrue(); + collection.deleteIndex(indexResult.getId()); + } + @ParameterizedTest @MethodSource("cols") void indexEstimates(ArangoCollection collection) { From 51acee999b69ba89ca7d458f16001341d0511d9f Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Wed, 28 Feb 2024 12:45:30 +0100 Subject: [PATCH 3/4] separate API for MDI and MDI-prefixed --- .../java/com/arangodb/ArangoCollection.java | 24 ++++++++++++------- .../com/arangodb/ArangoCollectionAsync.java | 12 +++++++--- .../internal/ArangoCollectionAsyncImpl.java | 7 +++++- .../internal/ArangoCollectionImpl.java | 7 +++++- .../arangodb/ArangoCollectionAsyncTest.java | 2 +- .../com/arangodb/ArangoCollectionTest.java | 2 +- 6 files changed, 39 insertions(+), 15 deletions(-) diff --git a/core/src/main/java/com/arangodb/ArangoCollection.java b/core/src/main/java/com/arangodb/ArangoCollection.java index 4362502aa..f38fffd5a 100644 --- a/core/src/main/java/com/arangodb/ArangoCollection.java +++ b/core/src/main/java/com/arangodb/ArangoCollection.java @@ -665,27 +665,35 @@ MultiDocumentEntity> deleteDocuments( * @return information about the index * @see API Documentation * @since ArangoDB 3.9 - * @deprecated since ArangoDB 3.12, use {@link #ensureMDIndex(Iterable, AbstractMDIndexOptions)} instead. + * @deprecated since ArangoDB 3.12, use {@link #ensureMDIndex(Iterable, MDIndexOptions)} or + * {@link #ensureMDPrefixedIndex(Iterable, MDPrefixedIndexOptions)} instead. */ @Deprecated IndexEntity ensureZKDIndex(Iterable fields, ZKDIndexOptions options); /** - * Creates a multi-dimensional (prefixed) index for the collection, if it does not already exist. + * Creates a multi-dimensional index for the collection, if it does not already exist. * * @param fields A list of attribute names used for each dimension * @param options Additional options, can be null. - * Can be an instance of: - *
    - *
  • {@link MDIndexOptions} to create a multi-dimensional index
  • - *
  • {@link MDPrefixedIndexOptions} to create a multi-dimensional prefixed index
  • - *
* * @return information about the index * @see API Documentation * @since ArangoDB 3.12 */ - IndexEntity ensureMDIndex(Iterable fields, AbstractMDIndexOptions options); + IndexEntity ensureMDIndex(Iterable fields, MDIndexOptions options); + + /** + * Creates a multi-dimensional prefixed index for the collection, if it does not already exist. + * + * @param fields A list of attribute names used for each dimension + * @param options Additional options, cannot be null. + * + * @return information about the index + * @see API Documentation + * @since ArangoDB 3.12 + */ + IndexEntity ensureMDPrefixedIndex(Iterable fields, MDPrefixedIndexOptions options); /** * Creates an inverted index for the collection, if it does not already exist. diff --git a/core/src/main/java/com/arangodb/ArangoCollectionAsync.java b/core/src/main/java/com/arangodb/ArangoCollectionAsync.java index a753adc23..8de03b874 100644 --- a/core/src/main/java/com/arangodb/ArangoCollectionAsync.java +++ b/core/src/main/java/com/arangodb/ArangoCollectionAsync.java @@ -306,15 +306,21 @@ CompletableFuture>> deleteDocume /** * Asynchronous version of {@link ArangoCollection#ensureZKDIndex(Iterable, ZKDIndexOptions)} * - * @deprecated since ArangoDB 3.12, use {@link #ensureMDIndex(Iterable, MDIndexOptions)} instead. + * @deprecated since ArangoDB 3.12, use {@link #ensureMDIndex(Iterable, MDIndexOptions)} or + * {@link #ensureMDPrefixedIndex(Iterable, MDPrefixedIndexOptions)} instead. */ @Deprecated CompletableFuture ensureZKDIndex(Iterable fields, ZKDIndexOptions options); /** - * Asynchronous version of {@link ArangoCollection#ensureMDIndex(Iterable, AbstractMDIndexOptions)} + * Asynchronous version of {@link ArangoCollection#ensureMDIndex(Iterable, MDIndexOptions)} */ - CompletableFuture ensureMDIndex(Iterable fields, AbstractMDIndexOptions options); + CompletableFuture ensureMDIndex(Iterable fields, MDIndexOptions options); + + /** + * Asynchronous version of {@link ArangoCollection#ensureMDPrefixedIndex(Iterable, MDPrefixedIndexOptions)} + */ + CompletableFuture ensureMDPrefixedIndex(Iterable fields, MDPrefixedIndexOptions options); /** * Asynchronous version of {@link ArangoCollection#ensureInvertedIndex(InvertedIndexOptions)} diff --git a/core/src/main/java/com/arangodb/internal/ArangoCollectionAsyncImpl.java b/core/src/main/java/com/arangodb/internal/ArangoCollectionAsyncImpl.java index 32c82706b..17fb9a8b2 100644 --- a/core/src/main/java/com/arangodb/internal/ArangoCollectionAsyncImpl.java +++ b/core/src/main/java/com/arangodb/internal/ArangoCollectionAsyncImpl.java @@ -388,7 +388,12 @@ public CompletableFuture ensureZKDIndex(final Iterable fiel } @Override - public CompletableFuture ensureMDIndex(final Iterable fields, final AbstractMDIndexOptions options) { + public CompletableFuture ensureMDIndex(final Iterable fields, final MDIndexOptions options) { + return executorAsync().execute(() -> createMDIndexRequest(fields, options), IndexEntity.class); + } + + @Override + public CompletableFuture ensureMDPrefixedIndex(final Iterable fields, final MDPrefixedIndexOptions options) { return executorAsync().execute(() -> createMDIndexRequest(fields, options), IndexEntity.class); } diff --git a/core/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java b/core/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java index 98788d13e..40cb4276e 100644 --- a/core/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java +++ b/core/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java @@ -379,7 +379,12 @@ public IndexEntity ensureZKDIndex(final Iterable fields, final ZKDIndexO } @Override - public IndexEntity ensureMDIndex(final Iterable fields, final AbstractMDIndexOptions options) { + public IndexEntity ensureMDIndex(final Iterable fields, final MDIndexOptions options) { + return executorSync().execute(createMDIndexRequest(fields, options), IndexEntity.class); + } + + @Override + public IndexEntity ensureMDPrefixedIndex(final Iterable fields, final MDPrefixedIndexOptions options) { return executorSync().execute(createMDIndexRequest(fields, options), IndexEntity.class); } diff --git a/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java b/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java index 41d1d68a3..a2f3adb82 100644 --- a/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java +++ b/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java @@ -1691,7 +1691,7 @@ void createMDPrefixedIndexWithOptions(ArangoCollectionAsync collection) throws E String f1 = "field-" + rnd(); String f2 = "field-" + rnd(); - final IndexEntity indexResult = collection.ensureMDIndex(Arrays.asList(f1, f2), options).get(); + final IndexEntity indexResult = collection.ensureMDPrefixedIndex(Arrays.asList(f1, f2), options).get(); assertThat(indexResult.getType()).isEqualTo(IndexType.mdiPrefixed); assertThat(indexResult.getId()).startsWith(COLLECTION_NAME); assertThat(indexResult.getName()).isEqualTo(name); diff --git a/driver/src/test/java/com/arangodb/ArangoCollectionTest.java b/driver/src/test/java/com/arangodb/ArangoCollectionTest.java index aae1715d7..d00603654 100644 --- a/driver/src/test/java/com/arangodb/ArangoCollectionTest.java +++ b/driver/src/test/java/com/arangodb/ArangoCollectionTest.java @@ -1716,7 +1716,7 @@ void createMDPrefixedIndexWithOptions(ArangoCollection collection) { String f1 = "field-" + rnd(); String f2 = "field-" + rnd(); - final IndexEntity indexResult = collection.ensureMDIndex(Arrays.asList(f1, f2), options); + final IndexEntity indexResult = collection.ensureMDPrefixedIndex(Arrays.asList(f1, f2), options); assertThat(indexResult.getType()).isEqualTo(IndexType.mdiPrefixed); assertThat(indexResult.getId()).startsWith(COLLECTION_NAME); assertThat(indexResult.getName()).isEqualTo(name); From b4640f61f95dc27e7a4514334ef7f3a0d2e56792 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Wed, 28 Feb 2024 13:04:53 +0100 Subject: [PATCH 4/4] added MDI fields to IndexEntity --- .../java/com/arangodb/entity/IndexEntity.java | 11 +++++++++++ .../com/arangodb/ArangoCollectionAsyncTest.java | 15 +++++++-------- .../java/com/arangodb/ArangoCollectionTest.java | 15 +++++++-------- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/core/src/main/java/com/arangodb/entity/IndexEntity.java b/core/src/main/java/com/arangodb/entity/IndexEntity.java index 06bf9c65f..b488845b7 100644 --- a/core/src/main/java/com/arangodb/entity/IndexEntity.java +++ b/core/src/main/java/com/arangodb/entity/IndexEntity.java @@ -20,6 +20,8 @@ package com.arangodb.entity; +import com.arangodb.model.MDIFieldValueTypes; + import java.util.Collection; /** @@ -45,6 +47,8 @@ public final class IndexEntity { private Boolean cacheEnabled; private Collection storedValues; private Boolean legacyPolygons; + private MDIFieldValueTypes fieldValueTypes; + private Collection prefixFields; public IndexEntity() { super(); @@ -122,4 +126,11 @@ public Boolean getLegacyPolygons() { return legacyPolygons; } + public MDIFieldValueTypes getFieldValueTypes() { + return fieldValueTypes; + } + + public Collection getPrefixFields() { + return prefixFields; + } } diff --git a/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java b/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java index a2f3adb82..d97300619 100644 --- a/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java +++ b/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java @@ -1627,8 +1627,8 @@ void createMDIndex(ArangoCollectionAsync collection) throws ExecutionException, final IndexEntity indexResult = collection.ensureMDIndex(Arrays.asList(f1, f2), null).get(); assertThat(indexResult).isNotNull(); assertThat(indexResult.getConstraint()).isNull(); - assertThat(indexResult.getFields()).contains(f1); - assertThat(indexResult.getFields()).contains(f2); + assertThat(indexResult.getFields()).contains(f1, f2); + assertThat(indexResult.getFieldValueTypes()).isEqualTo(MDIFieldValueTypes.DOUBLE); assertThat(indexResult.getId()).startsWith(COLLECTION_NAME); assertThat(indexResult.getIsNewlyCreated()).isTrue(); assertThat(indexResult.getMinLength()).isNull(); @@ -1665,9 +1665,8 @@ void createMDIndexWithOptions(ArangoCollectionAsync collection) throws Execution assertThat(indexResult.getStoredValues()) .hasSize(2) .contains("v1", "v2"); - assertThat(indexResult.getFields()) - .contains(f1) - .contains(f2); + assertThat(indexResult.getFields()).contains(f1, f2); + assertThat(indexResult.getFieldValueTypes()).isEqualTo(MDIFieldValueTypes.DOUBLE); assertThat(indexResult.getIsNewlyCreated()).isTrue(); collection.deleteIndex(indexResult.getId()).get(); } @@ -1701,9 +1700,9 @@ void createMDPrefixedIndexWithOptions(ArangoCollectionAsync collection) throws E assertThat(indexResult.getStoredValues()) .hasSize(2) .contains("v1", "v2"); - assertThat(indexResult.getFields()) - .contains(f1) - .contains(f2); + assertThat(indexResult.getFields()).contains(f1, f2); + assertThat(indexResult.getFieldValueTypes()).isEqualTo(MDIFieldValueTypes.DOUBLE); + assertThat(indexResult.getPrefixFields()).contains("p1", "p2"); assertThat(indexResult.getIsNewlyCreated()).isTrue(); collection.deleteIndex(indexResult.getId()).get(); } diff --git a/driver/src/test/java/com/arangodb/ArangoCollectionTest.java b/driver/src/test/java/com/arangodb/ArangoCollectionTest.java index d00603654..092f1e1d3 100644 --- a/driver/src/test/java/com/arangodb/ArangoCollectionTest.java +++ b/driver/src/test/java/com/arangodb/ArangoCollectionTest.java @@ -1652,8 +1652,8 @@ void createMDIndex(ArangoCollection collection) { final IndexEntity indexResult = collection.ensureMDIndex(Arrays.asList(f1, f2), null); assertThat(indexResult).isNotNull(); assertThat(indexResult.getConstraint()).isNull(); - assertThat(indexResult.getFields()).contains(f1); - assertThat(indexResult.getFields()).contains(f2); + assertThat(indexResult.getFields()).contains(f1, f2); + assertThat(indexResult.getFieldValueTypes()).isEqualTo(MDIFieldValueTypes.DOUBLE); assertThat(indexResult.getId()).startsWith(COLLECTION_NAME); assertThat(indexResult.getIsNewlyCreated()).isTrue(); assertThat(indexResult.getMinLength()).isNull(); @@ -1690,9 +1690,8 @@ void createMDIndexWithOptions(ArangoCollection collection) { assertThat(indexResult.getStoredValues()) .hasSize(2) .contains("v1", "v2"); - assertThat(indexResult.getFields()) - .contains(f1) - .contains(f2); + assertThat(indexResult.getFields()).contains(f1, f2); + assertThat(indexResult.getFieldValueTypes()).isEqualTo(MDIFieldValueTypes.DOUBLE); assertThat(indexResult.getIsNewlyCreated()).isTrue(); collection.deleteIndex(indexResult.getId()); } @@ -1726,9 +1725,9 @@ void createMDPrefixedIndexWithOptions(ArangoCollection collection) { assertThat(indexResult.getStoredValues()) .hasSize(2) .contains("v1", "v2"); - assertThat(indexResult.getFields()) - .contains(f1) - .contains(f2); + assertThat(indexResult.getFields()).contains(f1, f2); + assertThat(indexResult.getFieldValueTypes()).isEqualTo(MDIFieldValueTypes.DOUBLE); + assertThat(indexResult.getPrefixFields()).contains("p1", "p2"); assertThat(indexResult.getIsNewlyCreated()).isTrue(); collection.deleteIndex(indexResult.getId()); }