Skip to content

[DE-742] Multi Dimentional index #544

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 4, 2024
Merged
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
27 changes: 27 additions & 0 deletions core/src/main/java/com/arangodb/ArangoCollection.java
Original file line number Diff line number Diff line change
Expand Up @@ -665,9 +665,36 @@ <T> MultiDocumentEntity<DocumentDeleteEntity<T>> deleteDocuments(
* @return information about the index
* @see <a href="https://www.arangodb.com/docs/stable/http/indexes-multi-dim.html">API Documentation</a>
* @since ArangoDB 3.9
* @deprecated since ArangoDB 3.12, use {@link #ensureMDIndex(Iterable, MDIndexOptions)} or
* {@link #ensureMDPrefixedIndex(Iterable, MDPrefixedIndexOptions)} instead.
*/
@Deprecated
IndexEntity ensureZKDIndex(Iterable<String> 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 <a href="https://docs.arangodb.com/devel/develop/http-api/indexes/multi-dimensional">API Documentation</a>
* @since ArangoDB 3.12
*/
IndexEntity ensureMDIndex(Iterable<String> 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 <a href="https://docs.arangodb.com/devel/develop/http-api/indexes/multi-dimensional">API Documentation</a>
* @since ArangoDB 3.12
*/
IndexEntity ensureMDPrefixedIndex(Iterable<String> fields, MDPrefixedIndexOptions options);

/**
* Creates an inverted index for the collection, if it does not already exist.
*
Expand Down
14 changes: 14 additions & 0 deletions core/src/main/java/com/arangodb/ArangoCollectionAsync.java
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,23 @@ <T> CompletableFuture<MultiDocumentEntity<DocumentDeleteEntity<T>>> deleteDocume

/**
* Asynchronous version of {@link ArangoCollection#ensureZKDIndex(Iterable, ZKDIndexOptions)}
*
* @deprecated since ArangoDB 3.12, use {@link #ensureMDIndex(Iterable, MDIndexOptions)} or
* {@link #ensureMDPrefixedIndex(Iterable, MDPrefixedIndexOptions)} instead.
*/
@Deprecated
CompletableFuture<IndexEntity> ensureZKDIndex(Iterable<String> fields, ZKDIndexOptions options);

/**
* Asynchronous version of {@link ArangoCollection#ensureMDIndex(Iterable, MDIndexOptions)}
*/
CompletableFuture<IndexEntity> ensureMDIndex(Iterable<String> fields, MDIndexOptions options);

/**
* Asynchronous version of {@link ArangoCollection#ensureMDPrefixedIndex(Iterable, MDPrefixedIndexOptions)}
*/
CompletableFuture<IndexEntity> ensureMDPrefixedIndex(Iterable<String> fields, MDPrefixedIndexOptions options);

/**
* Asynchronous version of {@link ArangoCollection#ensureInvertedIndex(InvertedIndexOptions)}
*/
Expand Down
11 changes: 11 additions & 0 deletions core/src/main/java/com/arangodb/entity/IndexEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

package com.arangodb.entity;

import com.arangodb.model.MDIFieldValueTypes;

import java.util.Collection;

/**
Expand All @@ -45,6 +47,8 @@ public final class IndexEntity {
private Boolean cacheEnabled;
private Collection<String> storedValues;
private Boolean legacyPolygons;
private MDIFieldValueTypes fieldValueTypes;
private Collection<String> prefixFields;

public IndexEntity() {
super();
Expand Down Expand Up @@ -122,4 +126,11 @@ public Boolean getLegacyPolygons() {
return legacyPolygons;
}

public MDIFieldValueTypes getFieldValueTypes() {
return fieldValueTypes;
}

public Collection<String> getPrefixFields() {
return prefixFields;
}
}
17 changes: 17 additions & 0 deletions core/src/main/java/com/arangodb/entity/IndexType.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

package com.arangodb.entity;

import com.fasterxml.jackson.annotation.JsonProperty;

/**
* @author Mark Vollmary
* @author Heiko Kernbach
Expand Down Expand Up @@ -52,6 +54,21 @@ public enum IndexType {

zkd,

/**
* Multi Dimensional Index
* @see <a href="https://docs.arangodb.com/devel/index-and-search/indexing/working-with-indexes/multi-dimensional-indexes">Ref Doc</a>
* @since ArangoDB 3.12
*/
mdi,

/**
* Multi Dimensional Prefixed Index
* @see <a href="https://docs.arangodb.com/devel/index-and-search/indexing/working-with-indexes/multi-dimensional-indexes">Ref Doc</a>
* @since ArangoDB 3.12
*/
@JsonProperty("mdi-prefixed")
mdiPrefixed,

/**
* @since ArangoDB 3.10
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,16 @@ public CompletableFuture<IndexEntity> ensureZKDIndex(final Iterable<String> fiel
return executorAsync().execute(() -> createZKDIndexRequest(fields, options), IndexEntity.class);
}

@Override
public CompletableFuture<IndexEntity> ensureMDIndex(final Iterable<String> fields, final MDIndexOptions options) {
return executorAsync().execute(() -> createMDIndexRequest(fields, options), IndexEntity.class);
}

@Override
public CompletableFuture<IndexEntity> ensureMDPrefixedIndex(final Iterable<String> fields, final MDPrefixedIndexOptions options) {
return executorAsync().execute(() -> createMDIndexRequest(fields, options), IndexEntity.class);
}

@Override
public CompletableFuture<Collection<IndexEntity>> getIndexes() {
return executorAsync().execute(this::getIndexesRequest, getIndexesResponseDeserializer());
Expand Down
10 changes: 10 additions & 0 deletions core/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,16 @@ public IndexEntity ensureZKDIndex(final Iterable<String> fields, final ZKDIndexO
return executorSync().execute(createZKDIndexRequest(fields, options), IndexEntity.class);
}

@Override
public IndexEntity ensureMDIndex(final Iterable<String> fields, final MDIndexOptions options) {
return executorSync().execute(createMDIndexRequest(fields, options), IndexEntity.class);
}

@Override
public IndexEntity ensureMDPrefixedIndex(final Iterable<String> fields, final MDPrefixedIndexOptions options) {
return executorSync().execute(createMDIndexRequest(fields, options), IndexEntity.class);
}

@Override
public Collection<IndexEntity> getIndexes() {
return executorSync().execute(getIndexesRequest(), getIndexesResponseDeserializer());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,15 @@ protected InternalRequest createZKDIndexRequest(
return request;
}

protected InternalRequest createMDIndexRequest(
final Iterable<String> fields, final AbstractMDIndexOptions<?> options) {
final InternalRequest request = request(dbName, RequestType.POST, PATH_API_INDEX);
request.putQueryParam(COLLECTION, name);
AbstractMDIndexOptions<?> opts = options != null ? options : new MDIndexOptions().fieldValueTypes(MDIFieldValueTypes.DOUBLE);
request.setBody(getSerde().serialize(OptionsBuilder.build(opts, fields)));
return request;
}

protected InternalRequest getIndexesRequest() {
final InternalRequest request = request(dbName, RequestType.GET, PATH_API_INDEX);
request.putQueryParam(COLLECTION, name);
Expand Down
143 changes: 143 additions & 0 deletions core/src/main/java/com/arangodb/model/AbstractMDIndexOptions.java
Original file line number Diff line number Diff line change
@@ -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 <a href="https://docs.arangodb.com/devel/develop/http-api/indexes/multi-dimensional">API Documentation</a>
* @since ArangoDB 3.12
*/
@NoRawTypesInspection
public abstract class AbstractMDIndexOptions<T extends AbstractMDIndexOptions<T>> extends IndexOptions<T> {

private Iterable<String> fields;
private Boolean unique;
private MDIFieldValueTypes fieldValueTypes;
private Boolean estimates;
private Boolean sparse;
private Iterable<String> storedValues;


public AbstractMDIndexOptions() {
super();
}

public abstract IndexType getType();

public Iterable<String> 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<String> 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<String> 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<String> storedValues) {
this.storedValues = storedValues;
return getThis();
}

}
8 changes: 8 additions & 0 deletions core/src/main/java/com/arangodb/model/MDIFieldValueTypes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.arangodb.model;

import com.fasterxml.jackson.annotation.JsonProperty;

public enum MDIFieldValueTypes {
@JsonProperty("double")
DOUBLE
}
47 changes: 47 additions & 0 deletions core/src/main/java/com/arangodb/model/MDIndexOptions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* 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 <a href="https://docs.arangodb.com/devel/develop/http-api/indexes/multi-dimensional">API Documentation</a>
* @since ArangoDB 3.12
*/
public final class MDIndexOptions extends AbstractMDIndexOptions<MDIndexOptions> {

public MDIndexOptions() {
super();
}

@Override
public IndexType getType() {
return IndexType.mdi;
}

@Override
MDIndexOptions getThis() {
return this;
}

}
Loading