Skip to content

Commit fb1791a

Browse files
committed
Changing collection to cursor, iprove distinct, fix getSortVector, add dot notation on documents and rows
1 parent 76fcffd commit fb1791a

29 files changed

+518
-956
lines changed

astra-db-java/src/main/java/com/datastax/astra/client/collections/Collection.java

Lines changed: 112 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,21 @@
4949
import com.datastax.astra.client.core.options.BaseOptions;
5050
import com.datastax.astra.client.core.commands.Command;
5151
import com.datastax.astra.client.collections.commands.cursor.CollectionCursor;
52-
import com.datastax.astra.client.collections.commands.cursor.CollectionDistinctIterable;
53-
import com.datastax.astra.client.core.paging.FindIterable;
5452
import com.datastax.astra.client.core.paging.Page;
5553
import com.datastax.astra.client.core.query.Filter;
5654
import com.datastax.astra.client.core.query.Filters;
5755
import com.datastax.astra.client.core.DataAPIKeywords;
5856
import com.datastax.astra.client.collections.definition.documents.types.ObjectId;
5957
import com.datastax.astra.client.collections.definition.documents.types.UUIDv6;
6058
import com.datastax.astra.client.collections.definition.documents.types.UUIDv7;
59+
import com.datastax.astra.client.core.query.Projection;
60+
import com.datastax.astra.client.core.vector.DataAPIVector;
6161
import com.datastax.astra.client.databases.Database;
6262
import com.datastax.astra.client.exceptions.DataAPIException;
6363
import com.datastax.astra.client.exceptions.UnexpectedDataAPIResponseException;
64+
import com.datastax.astra.client.tables.commands.options.TableDistinctOptions;
65+
import com.datastax.astra.client.tables.commands.options.TableFindOptions;
66+
import com.datastax.astra.client.tables.definition.rows.Row;
6467
import com.datastax.astra.internal.api.DataAPIResponse;
6568
import com.datastax.astra.internal.api.DataAPIStatus;
6669
import com.datastax.astra.internal.command.AbstractCommandRunner;
@@ -72,12 +75,7 @@
7275

7376
import java.time.Duration;
7477
import java.time.Instant;
75-
import java.util.ArrayList;
76-
import java.util.Arrays;
77-
import java.util.List;
78-
import java.util.Map;
79-
import java.util.Optional;
80-
import java.util.UUID;
78+
import java.util.*;
8179
import java.util.concurrent.Callable;
8280
import java.util.concurrent.CompletableFuture;
8381
import java.util.concurrent.ExecutionException;
@@ -88,6 +86,7 @@
8886
import java.util.concurrent.TimeoutException;
8987
import java.util.concurrent.atomic.AtomicInteger;
9088
import java.util.stream.Collectors;
89+
import java.util.stream.StreamSupport;
9190

9291
import static com.datastax.astra.client.core.options.DataAPIClientOptions.MAX_CHUNK_SIZE;
9392
import static com.datastax.astra.client.core.options.DataAPIClientOptions.MAX_COUNT;
@@ -799,7 +798,7 @@ private Callable<CollectionInsertManyResult> getInsertManyResultCallable(List<?
799798
}
800799

801800
// --------------------------
802-
// --- Find* ----
801+
// --- FindOne ----
803802
// --------------------------
804803

805804
/**
@@ -967,33 +966,6 @@ public CompletableFuture<Optional<T>> findOneASync(Filter filter, CollectionFind
967966
return CompletableFuture.supplyAsync(() -> findOne(filter, findOneOptions));
968967
}
969968

970-
971-
/**
972-
* Retrieves all documents in the collection.
973-
* <p>
974-
* This method returns an iterable interface that allows iterating over all documents in the collection,
975-
* without applying any filters. It leverages the default {@link CollectionFindOptions} for query execution.
976-
* </p>
977-
*
978-
* @return A {@link FindIterable} for iterating over all documents in the collection.
979-
*/
980-
public FindIterable<T> findAll() {
981-
return find(null, new CollectionFindOptions());
982-
}
983-
984-
/**
985-
* Retrieves all documents in the collection.
986-
* <p>
987-
* This method returns an iterable interface that allows iterating over all documents in the collection,
988-
* without applying any filters. It leverages the default {@link CollectionFindOptions} for query execution.
989-
* </p>
990-
*
991-
* @return A {@link CollectionCursor} for iterating over all documents in the collection.
992-
*/
993-
public CollectionCursor<T> findAllWithCursor() {
994-
return new CollectionCursor<T>(this, null, new CollectionFindOptions());
995-
}
996-
997969
/**
998970
* Retrieves a document by its identifier from the collection.
999971
* <p>
@@ -1010,16 +982,22 @@ public Optional<T> findById(Object id) {
1010982
return findOne(Filters.eq(id));
1011983
}
1012984

985+
// -------------------------
986+
// --- find ----
987+
// -------------------------
988+
1013989
/**
1014990
* Finds all documents in the collection.
1015991
*
1016992
* @param filter
1017993
* the query filter
994+
* @param options
995+
* options of find one
1018996
* @return
1019997
* the find iterable interface
1020998
*/
1021-
public FindIterable<T> find(Filter filter) {
1022-
return find(filter, new CollectionFindOptions());
999+
public CollectionCursor<T, T> find(Filter filter, CollectionFindOptions options) {
1000+
return new CollectionCursor<>(this, filter, options, getDocumentClass());
10231001
}
10241002

10251003
/**
@@ -1032,19 +1010,45 @@ public FindIterable<T> find(Filter filter) {
10321010
* @return
10331011
* the find iterable interface
10341012
*/
1035-
public FindIterable<T> find(Filter filter, CollectionFindOptions options) {
1036-
return new FindIterable<>(this, filter, options);
1013+
public <R> CollectionCursor<T, R> find(Filter filter, CollectionFindOptions options, Class<R> newDocType) {
1014+
return new CollectionCursor<>(this, filter, options, newDocType);
10371015
}
10381016

10391017
/**
10401018
* Finds all documents in the collection.
1019+
*
1020+
* @param filter
1021+
* the query filter
1022+
* @return
1023+
* the find iterable interface
1024+
*/
1025+
public CollectionCursor<T, T> find(Filter filter) {
1026+
return new CollectionCursor<>(this, filter, new CollectionFindOptions(), getDocumentClass());
1027+
}
1028+
1029+
/**
1030+
* Finds all documents in the collection.
1031+
*
10411032
* @param options
10421033
* options of find one
10431034
* @return
10441035
* the find iterable interface
10451036
*/
1046-
public FindIterable<T> find(CollectionFindOptions options) {
1047-
return find(null, options);
1037+
public CollectionCursor<T, T> find(CollectionFindOptions options) {
1038+
return new CollectionCursor<>(this, null, options, getDocumentClass());
1039+
}
1040+
1041+
/**
1042+
* Retrieves all documents in the collection.
1043+
* <p>
1044+
* This method returns an iterable interface that allows iterating over all documents in the collection,
1045+
* without applying any filters. It leverages the default {@link CollectionFindOptions} for query execution.
1046+
* </p>
1047+
*
1048+
* @return A {@link CollectionCursor} for iterating over all documents in the collection.
1049+
*/
1050+
public CollectionCursor<T, T> findAll() {
1051+
return find(null, new CollectionFindOptions());
10481052
}
10491053

10501054
/**
@@ -1072,23 +1076,23 @@ public FindIterable<T> find(CollectionFindOptions options) {
10721076
public Page<T> findPage(Filter filter, CollectionFindOptions options) {
10731077
Command findCommand = Command
10741078
.create("find")
1075-
.withFilter(filter)
1076-
.withSort(options.getSortArray())
1077-
.withProjection(options.getProjectionArray())
1078-
.withOptions(new Document()
1079-
.appendIfNotNull("skip", options.skip())
1080-
.appendIfNotNull("limit", options.limit())
1081-
.appendIfNotNull(INPUT_PAGE_STATE, options.pageState())
1082-
.appendIfNotNull(INPUT_INCLUDE_SORT_VECTOR, options.includeSortVector())
1083-
.appendIfNotNull(INPUT_INCLUDE_SIMILARITY, options.includeSimilarity()));
1079+
.withFilter(filter);
1080+
if (options != null) {
1081+
findCommand.withSort(options.getSortArray())
1082+
.withProjection(options.getProjectionArray())
1083+
.withOptions(new Document()
1084+
.appendIfNotNull("skip", options.skip())
1085+
.appendIfNotNull("limit", options.limit())
1086+
.appendIfNotNull(INPUT_PAGE_STATE, options.pageState())
1087+
.appendIfNotNull(INPUT_INCLUDE_SORT_VECTOR, options.includeSortVector())
1088+
.appendIfNotNull(INPUT_INCLUDE_SIMILARITY, options.includeSimilarity()));
1089+
}
10841090
DataAPIResponse apiResponse = runCommand(findCommand, options);
10851091

10861092
// load sortVector if available
1087-
float[] sortVector = null;
1088-
if (options.includeSortVector() != null &&
1089-
apiResponse.getStatus() != null &&
1090-
apiResponse.getStatus().get(SORT_VECTOR.getKeyword()) != null) {
1091-
sortVector = apiResponse.getStatus().get(SORT_VECTOR.getKeyword(), float[].class);
1093+
DataAPIVector sortVector = null;
1094+
if (options != null && options.includeSortVector() != null && apiResponse.getStatus() != null) {
1095+
sortVector = apiResponse.getStatus().getSortVector();
10921096
}
10931097

10941098
return new Page<>(
@@ -1125,43 +1129,74 @@ public CompletableFuture<Page<T>> findPageASync(Filter filter, CollectionFindOpt
11251129
return CompletableFuture.supplyAsync(() -> findPage(filter, options));
11261130
}
11271131

1128-
// --------------------------
1129-
// --- Distinct ----
1130-
// --------------------------
1132+
// -------------------------
1133+
// --- distinct ----
1134+
// -------------------------
11311135

11321136
/**
1133-
* Gets the distinct values of the specified field name.
1134-
* The iteration is performed at CLIENT-SIDE and will exhaust all the collections elements.
1137+
* Return a list of distinct values for the given field name.
11351138
*
11361139
* @param fieldName
1137-
* the field name
1140+
* name of the field
1141+
* @param filter
1142+
* filter to apply
11381143
* @param resultClass
1139-
* the class to cast any distinct items into.
1140-
* @param <F>
1141-
* the target type of the iterable.
1144+
* class of the result
1145+
* @param <R>
1146+
* type of the result
11421147
* @return
1143-
* an iterable of distinct values
1148+
* list of distinct values
11441149
*/
1145-
public <F> CollectionDistinctIterable<T, F> distinct(String fieldName, Class<F> resultClass) {
1146-
return distinct(fieldName, null, resultClass);
1150+
public <R> Set<R> distinct(String fieldName, Filter filter, Class<R> resultClass) {
1151+
return distinct(fieldName, filter, resultClass, null);
11471152
}
11481153

11491154
/**
1150-
* Gets the distinct values of the specified field name.
1155+
* Return a list of distinct values for the given field name.
11511156
*
11521157
* @param fieldName
1153-
* the field name
1158+
* name of the field
1159+
* @param resultClass
1160+
* class of the result
1161+
* @param <R>
1162+
* type of the result
1163+
* @return
1164+
* list of distinct values
1165+
*/
1166+
public <R> Set<R> distinct(String fieldName, Class<R> resultClass) {
1167+
return distinct(fieldName, null, resultClass, null);
1168+
}
1169+
1170+
/**
1171+
* Return a list of distinct values for the given field name.
1172+
*
1173+
* @param fieldName
1174+
* name of the field
11541175
* @param filter
1155-
* the query filter
1176+
* filter to apply
11561177
* @param resultClass
1157-
* the class to cast any distinct items into.
1158-
* @param <F>
1159-
* the target type of the iterable.
1178+
* class of the result
1179+
* @param options
1180+
* options to apply to the operation
11601181
* @return
1161-
* an iterable of distinct values
1182+
* list of distinct values
1183+
* @param <R>
1184+
* type of the result
11621185
*/
1163-
public <F> CollectionDistinctIterable<T, F> distinct(String fieldName, Filter filter, Class<F> resultClass) {
1164-
return new CollectionDistinctIterable<>(this, fieldName, filter, resultClass);
1186+
public <R> Set<R> distinct(String fieldName, Filter filter, Class<R> resultClass, TableDistinctOptions options) {
1187+
Assert.hasLength(fieldName, "fieldName");
1188+
Assert.notNull(resultClass, "resultClass");
1189+
// Building a convenient find options
1190+
CollectionFindOptions findOptions = new CollectionFindOptions()
1191+
.projection(Projection.include(fieldName));
1192+
// Overriding options
1193+
if (options != null && options.getDataAPIClientOptions() != null) {
1194+
findOptions.dataAPIClientOptions(options.getDataAPIClientOptions());
1195+
}
1196+
// Exhausting the list of distinct values
1197+
return StreamSupport.stream(find(filter, findOptions, Document.class).spliterator(), true)
1198+
.map(doc -> doc.get(fieldName, resultClass))
1199+
.collect(Collectors.toSet());
11651200
}
11661201

11671202
// ----------------------------

0 commit comments

Comments
 (0)