Skip to content

Commit 6a34326

Browse files
committed
[DE-742] Multi Dimentional index (#544)
* mdi * mdi prefixed * separate API for MDI and MDI-prefixed * added MDI fields to IndexEntity
1 parent 6e1306f commit 6a34326

15 files changed

+548
-0
lines changed

Diff for: core/src/main/java/com/arangodb/ArangoCollection.java

+27
Original file line numberDiff line numberDiff line change
@@ -665,9 +665,36 @@ <T> MultiDocumentEntity<DocumentDeleteEntity<T>> deleteDocuments(
665665
* @return information about the index
666666
* @see <a href="https://www.arangodb.com/docs/stable/http/indexes-multi-dim.html">API Documentation</a>
667667
* @since ArangoDB 3.9
668+
* @deprecated since ArangoDB 3.12, use {@link #ensureMDIndex(Iterable, MDIndexOptions)} or
669+
* {@link #ensureMDPrefixedIndex(Iterable, MDPrefixedIndexOptions)} instead.
668670
*/
671+
@Deprecated
669672
IndexEntity ensureZKDIndex(Iterable<String> fields, ZKDIndexOptions options);
670673

674+
/**
675+
* Creates a multi-dimensional index for the collection, if it does not already exist.
676+
*
677+
* @param fields A list of attribute names used for each dimension
678+
* @param options Additional options, can be null.
679+
*
680+
* @return information about the index
681+
* @see <a href="https://docs.arangodb.com/devel/develop/http-api/indexes/multi-dimensional">API Documentation</a>
682+
* @since ArangoDB 3.12
683+
*/
684+
IndexEntity ensureMDIndex(Iterable<String> fields, MDIndexOptions options);
685+
686+
/**
687+
* Creates a multi-dimensional prefixed index for the collection, if it does not already exist.
688+
*
689+
* @param fields A list of attribute names used for each dimension
690+
* @param options Additional options, cannot be null.
691+
*
692+
* @return information about the index
693+
* @see <a href="https://docs.arangodb.com/devel/develop/http-api/indexes/multi-dimensional">API Documentation</a>
694+
* @since ArangoDB 3.12
695+
*/
696+
IndexEntity ensureMDPrefixedIndex(Iterable<String> fields, MDPrefixedIndexOptions options);
697+
671698
/**
672699
* Creates an inverted index for the collection, if it does not already exist.
673700
*

Diff for: core/src/main/java/com/arangodb/ArangoCollectionAsync.java

+14
Original file line numberDiff line numberDiff line change
@@ -305,9 +305,23 @@ <T> CompletableFuture<MultiDocumentEntity<DocumentDeleteEntity<T>>> deleteDocume
305305

306306
/**
307307
* Asynchronous version of {@link ArangoCollection#ensureZKDIndex(Iterable, ZKDIndexOptions)}
308+
*
309+
* @deprecated since ArangoDB 3.12, use {@link #ensureMDIndex(Iterable, MDIndexOptions)} or
310+
* {@link #ensureMDPrefixedIndex(Iterable, MDPrefixedIndexOptions)} instead.
308311
*/
312+
@Deprecated
309313
CompletableFuture<IndexEntity> ensureZKDIndex(Iterable<String> fields, ZKDIndexOptions options);
310314

315+
/**
316+
* Asynchronous version of {@link ArangoCollection#ensureMDIndex(Iterable, MDIndexOptions)}
317+
*/
318+
CompletableFuture<IndexEntity> ensureMDIndex(Iterable<String> fields, MDIndexOptions options);
319+
320+
/**
321+
* Asynchronous version of {@link ArangoCollection#ensureMDPrefixedIndex(Iterable, MDPrefixedIndexOptions)}
322+
*/
323+
CompletableFuture<IndexEntity> ensureMDPrefixedIndex(Iterable<String> fields, MDPrefixedIndexOptions options);
324+
311325
/**
312326
* Asynchronous version of {@link ArangoCollection#ensureInvertedIndex(InvertedIndexOptions)}
313327
*/

Diff for: core/src/main/java/com/arangodb/entity/IndexEntity.java

+11
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
package com.arangodb.entity;
2222

23+
import com.arangodb.model.MDIFieldValueTypes;
24+
2325
import java.util.Collection;
2426

2527
/**
@@ -45,6 +47,8 @@ public final class IndexEntity {
4547
private Boolean cacheEnabled;
4648
private Collection<String> storedValues;
4749
private Boolean legacyPolygons;
50+
private MDIFieldValueTypes fieldValueTypes;
51+
private Collection<String> prefixFields;
4852

4953
public IndexEntity() {
5054
super();
@@ -122,4 +126,11 @@ public Boolean getLegacyPolygons() {
122126
return legacyPolygons;
123127
}
124128

129+
public MDIFieldValueTypes getFieldValueTypes() {
130+
return fieldValueTypes;
131+
}
132+
133+
public Collection<String> getPrefixFields() {
134+
return prefixFields;
135+
}
125136
}

Diff for: core/src/main/java/com/arangodb/entity/IndexType.java

+17
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
package com.arangodb.entity;
2222

23+
import com.fasterxml.jackson.annotation.JsonProperty;
24+
2325
/**
2426
* @author Mark Vollmary
2527
* @author Heiko Kernbach
@@ -52,6 +54,21 @@ public enum IndexType {
5254

5355
zkd,
5456

57+
/**
58+
* Multi Dimensional Index
59+
* @see <a href="https://docs.arangodb.com/devel/index-and-search/indexing/working-with-indexes/multi-dimensional-indexes">Ref Doc</a>
60+
* @since ArangoDB 3.12
61+
*/
62+
mdi,
63+
64+
/**
65+
* Multi Dimensional Prefixed Index
66+
* @see <a href="https://docs.arangodb.com/devel/index-and-search/indexing/working-with-indexes/multi-dimensional-indexes">Ref Doc</a>
67+
* @since ArangoDB 3.12
68+
*/
69+
@JsonProperty("mdi-prefixed")
70+
mdiPrefixed,
71+
5572
/**
5673
* @since ArangoDB 3.10
5774
*/

Diff for: core/src/main/java/com/arangodb/internal/ArangoCollectionAsyncImpl.java

+10
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,16 @@ public CompletableFuture<IndexEntity> ensureZKDIndex(final Iterable<String> fiel
387387
return executorAsync().execute(() -> createZKDIndexRequest(fields, options), IndexEntity.class);
388388
}
389389

390+
@Override
391+
public CompletableFuture<IndexEntity> ensureMDIndex(final Iterable<String> fields, final MDIndexOptions options) {
392+
return executorAsync().execute(() -> createMDIndexRequest(fields, options), IndexEntity.class);
393+
}
394+
395+
@Override
396+
public CompletableFuture<IndexEntity> ensureMDPrefixedIndex(final Iterable<String> fields, final MDPrefixedIndexOptions options) {
397+
return executorAsync().execute(() -> createMDIndexRequest(fields, options), IndexEntity.class);
398+
}
399+
390400
@Override
391401
public CompletableFuture<Collection<IndexEntity>> getIndexes() {
392402
return executorAsync().execute(this::getIndexesRequest, getIndexesResponseDeserializer());

Diff for: core/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java

+10
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,16 @@ public IndexEntity ensureZKDIndex(final Iterable<String> fields, final ZKDIndexO
378378
return executorSync().execute(createZKDIndexRequest(fields, options), IndexEntity.class);
379379
}
380380

381+
@Override
382+
public IndexEntity ensureMDIndex(final Iterable<String> fields, final MDIndexOptions options) {
383+
return executorSync().execute(createMDIndexRequest(fields, options), IndexEntity.class);
384+
}
385+
386+
@Override
387+
public IndexEntity ensureMDPrefixedIndex(final Iterable<String> fields, final MDPrefixedIndexOptions options) {
388+
return executorSync().execute(createMDIndexRequest(fields, options), IndexEntity.class);
389+
}
390+
381391
@Override
382392
public Collection<IndexEntity> getIndexes() {
383393
return executorSync().execute(getIndexesRequest(), getIndexesResponseDeserializer());

Diff for: core/src/main/java/com/arangodb/internal/InternalArangoCollection.java

+9
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,15 @@ protected InternalRequest createZKDIndexRequest(
475475
return request;
476476
}
477477

478+
protected InternalRequest createMDIndexRequest(
479+
final Iterable<String> fields, final AbstractMDIndexOptions<?> options) {
480+
final InternalRequest request = request(dbName, RequestType.POST, PATH_API_INDEX);
481+
request.putQueryParam(COLLECTION, name);
482+
AbstractMDIndexOptions<?> opts = options != null ? options : new MDIndexOptions().fieldValueTypes(MDIFieldValueTypes.DOUBLE);
483+
request.setBody(getSerde().serialize(OptionsBuilder.build(opts, fields)));
484+
return request;
485+
}
486+
478487
protected InternalRequest getIndexesRequest() {
479488
final InternalRequest request = request(dbName, RequestType.GET, PATH_API_INDEX);
480489
request.putQueryParam(COLLECTION, name);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/*
2+
* DISCLAIMER
3+
*
4+
* Copyright 2016 ArangoDB GmbH, Cologne, Germany
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*
18+
* Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
*/
20+
21+
package com.arangodb.model;
22+
23+
import com.arangodb.arch.NoRawTypesInspection;
24+
import com.arangodb.entity.IndexType;
25+
26+
27+
/**
28+
* @author Michele Rastelli
29+
* @see <a href="https://docs.arangodb.com/devel/develop/http-api/indexes/multi-dimensional">API Documentation</a>
30+
* @since ArangoDB 3.12
31+
*/
32+
@NoRawTypesInspection
33+
public abstract class AbstractMDIndexOptions<T extends AbstractMDIndexOptions<T>> extends IndexOptions<T> {
34+
35+
private Iterable<String> fields;
36+
private Boolean unique;
37+
private MDIFieldValueTypes fieldValueTypes;
38+
private Boolean estimates;
39+
private Boolean sparse;
40+
private Iterable<String> storedValues;
41+
42+
43+
public AbstractMDIndexOptions() {
44+
super();
45+
}
46+
47+
public abstract IndexType getType();
48+
49+
public Iterable<String> getFields() {
50+
return fields;
51+
}
52+
53+
/**
54+
* @param fields A list of attribute names used for each dimension. Array expansions are not allowed.
55+
* @return options
56+
*/
57+
T fields(final Iterable<String> fields) {
58+
this.fields = fields;
59+
return getThis();
60+
}
61+
62+
public Boolean getUnique() {
63+
return unique;
64+
}
65+
66+
/**
67+
* @param unique if true, then create a unique index
68+
* @return options
69+
*/
70+
public T unique(final Boolean unique) {
71+
this.unique = unique;
72+
return getThis();
73+
}
74+
75+
public MDIFieldValueTypes getFieldValueTypes() {
76+
return fieldValueTypes;
77+
}
78+
79+
/**
80+
* @param fieldValueTypes must be {@link MDIFieldValueTypes#DOUBLE}, currently only doubles are supported as values.
81+
* @return options
82+
*/
83+
public T fieldValueTypes(final MDIFieldValueTypes fieldValueTypes) {
84+
this.fieldValueTypes = fieldValueTypes;
85+
return getThis();
86+
}
87+
88+
public Boolean getEstimates() {
89+
return estimates;
90+
}
91+
92+
/**
93+
* @param estimates controls whether index selectivity estimates are maintained for the index. Not maintaining index
94+
* selectivity estimates can have a slightly positive impact on write performance.
95+
* The downside of turning off index selectivity estimates is that the query optimizer is not able
96+
* to determine the usefulness of different competing indexes in AQL queries when there are
97+
* multiple candidate indexes to choose from.
98+
* The estimates attribute is optional and defaults to true if not set.
99+
* It cannot be disabled for non-unique multi-dimensional indexes because they have a fixed
100+
* selectivity estimate of 1.
101+
* @return options
102+
*/
103+
public T estimates(final Boolean estimates) {
104+
this.estimates = estimates;
105+
return getThis();
106+
}
107+
108+
public Boolean getSparse() {
109+
return sparse;
110+
}
111+
112+
/**
113+
* @param sparse if true, then create a sparse index
114+
* @return options
115+
*/
116+
public T sparse(final Boolean sparse) {
117+
this.sparse = sparse;
118+
return getThis();
119+
}
120+
121+
public Iterable<String> getStoredValues() {
122+
return storedValues;
123+
}
124+
125+
/**
126+
* @param storedValues can contain an array of paths to additional attributes to store in the index.
127+
* These additional attributes cannot be used for index lookups or for sorting, but they can be
128+
* used for projections. This allows an index to fully cover more queries and avoid extra
129+
* document lookups.
130+
* You can have the same attributes in storedValues and fields as the attributes in fields
131+
* cannot be used for projections, but you can also store additional attributes that are not
132+
* listed in fields.
133+
* Attributes in storedValues cannot overlap with the attributes specified in prefixFields.
134+
* Non-existing attributes are stored as null values inside storedValues.
135+
* The maximum number of attributes in storedValues is 32.
136+
* @return options
137+
*/
138+
public T storedValues(final Iterable<String> storedValues) {
139+
this.storedValues = storedValues;
140+
return getThis();
141+
}
142+
143+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.arangodb.model;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
5+
public enum MDIFieldValueTypes {
6+
@JsonProperty("double")
7+
DOUBLE
8+
}
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* DISCLAIMER
3+
*
4+
* Copyright 2016 ArangoDB GmbH, Cologne, Germany
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*
18+
* Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
*/
20+
21+
package com.arangodb.model;
22+
23+
import com.arangodb.entity.IndexType;
24+
25+
26+
/**
27+
* @author Michele Rastelli
28+
* @see <a href="https://docs.arangodb.com/devel/develop/http-api/indexes/multi-dimensional">API Documentation</a>
29+
* @since ArangoDB 3.12
30+
*/
31+
public final class MDIndexOptions extends AbstractMDIndexOptions<MDIndexOptions> {
32+
33+
public MDIndexOptions() {
34+
super();
35+
}
36+
37+
@Override
38+
public IndexType getType() {
39+
return IndexType.mdi;
40+
}
41+
42+
@Override
43+
MDIndexOptions getThis() {
44+
return this;
45+
}
46+
47+
}

0 commit comments

Comments
 (0)