Skip to content

Commit b183f1b

Browse files
committed
Introduce builder for $vectorSearch aggregation stage
JAVA-5117
1 parent deed10b commit b183f1b

File tree

17 files changed

+698
-78
lines changed

17 files changed

+698
-78
lines changed

driver-core/src/main/com/mongodb/client/model/Aggregates.java

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,17 @@
1717
package com.mongodb.client.model;
1818

1919
import com.mongodb.MongoNamespace;
20+
import com.mongodb.annotations.Beta;
2021
import com.mongodb.client.model.densify.DensifyOptions;
2122
import com.mongodb.client.model.densify.DensifyRange;
2223
import com.mongodb.client.model.fill.FillOptions;
2324
import com.mongodb.client.model.fill.FillOutputField;
2425
import com.mongodb.client.model.geojson.Point;
26+
import com.mongodb.client.model.search.FieldSearchPath;
2527
import com.mongodb.client.model.search.SearchCollector;
2628
import com.mongodb.client.model.search.SearchOperator;
2729
import com.mongodb.client.model.search.SearchOptions;
30+
import com.mongodb.client.model.search.VectorSearchOptions;
2831
import com.mongodb.lang.Nullable;
2932
import org.bson.BsonArray;
3033
import org.bson.BsonBoolean;
@@ -34,6 +37,7 @@
3437
import org.bson.BsonString;
3538
import org.bson.BsonType;
3639
import org.bson.BsonValue;
40+
import org.bson.Document;
3741
import org.bson.codecs.configuration.CodecRegistry;
3842
import org.bson.conversions.Bson;
3943

@@ -47,6 +51,7 @@
4751
import static com.mongodb.client.model.GeoNearOptions.geoNearOptions;
4852
import static com.mongodb.client.model.densify.DensifyOptions.densifyOptions;
4953
import static com.mongodb.client.model.search.SearchOptions.searchOptions;
54+
import static com.mongodb.client.model.search.VectorSearchOptions.vectorSearchOptions;
5055
import static com.mongodb.internal.Iterables.concat;
5156
import static com.mongodb.internal.client.model.Util.sizeAtLeast;
5257
import static java.util.Arrays.asList;
@@ -933,6 +938,80 @@ public static Bson searchMeta(final SearchCollector collector, final SearchOptio
933938
return new SearchStage("$searchMeta", notNull("collector", collector), notNull("options", options));
934939
}
935940

941+
/**
942+
* VAKOTODO
943+
* @param path
944+
* @param queryVector
945+
* @param index
946+
* @param numCandidates
947+
* @param limit
948+
* @return
949+
* @mongodb.atlas.manual / @mongodb.driver.dochub VAKOTODO
950+
* @mongodb.server.release 7.1
951+
* @since 4.11
952+
*/
953+
@Beta(Beta.Reason.SERVER)
954+
public static Bson vectorSearch(
955+
final FieldSearchPath path,
956+
final Iterable<Double> queryVector,
957+
final String index,
958+
final long numCandidates,
959+
final long limit) {
960+
return vectorSearch(notNull("path", path), notNull("queryVector", queryVector), notNull("index", index), numCandidates, limit,
961+
vectorSearchOptions());
962+
}
963+
964+
/**
965+
* VAKOTODO
966+
* @param queryVector
967+
* @param path
968+
* @param index
969+
* @param numCandidates
970+
* @param limit
971+
* @param options
972+
* @return
973+
* @mongodb.atlas.manual / @mongodb.driver.dochub VAKOTODO
974+
* @mongodb.server.release 7.1
975+
* @since 4.11
976+
*/
977+
@Beta(Beta.Reason.SERVER)
978+
public static Bson vectorSearch(
979+
final FieldSearchPath path,
980+
final Iterable<Double> queryVector,
981+
final String index,
982+
final long numCandidates,
983+
final long limit,
984+
final VectorSearchOptions options) {
985+
notNull("path", path);
986+
notNull("queryVector", queryVector);
987+
notNull("index", index);
988+
notNull("options", options);
989+
return new Bson() {
990+
@Override
991+
public <TDocument> BsonDocument toBsonDocument(final Class<TDocument> documentClass, final CodecRegistry codecRegistry) {
992+
Document specificationDoc = new Document("path", path.toValue())
993+
.append("queryVector", queryVector)
994+
.append("index", index)
995+
.append("numCandidates", numCandidates)
996+
.append("limit", limit);
997+
specificationDoc.putAll(options.toBsonDocument(documentClass, codecRegistry));
998+
return new Document("$vectorSearch", specificationDoc).toBsonDocument(documentClass, codecRegistry);
999+
}
1000+
1001+
@Override
1002+
public String toString() {
1003+
return "Stage{name=$vectorSearch"
1004+
+ ", field=" + queryVector
1005+
+ ", path=" + path
1006+
+ ", index=" + index
1007+
+ ", numCandidates=" + numCandidates
1008+
+ ", limit=" + limit
1009+
+ ", options=" + options
1010+
+ '}';
1011+
}
1012+
};
1013+
}
1014+
9361015
/**
9371016
* Creates an $unset pipeline stage that removes/excludes fields from documents
9381017
*

driver-core/src/main/com/mongodb/client/model/Filters.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,7 @@ private Filters() {
6161
}
6262

6363
/**
64-
* Creates a filter that matches all documents where the value of _id field equals the specified value. Note that this doesn't
65-
* actually generate a $eq operator, as the query language doesn't require it.
64+
* Creates a filter that matches all documents where the value of _id field equals the specified value.
6665
*
6766
* @param value the value, which may be null
6867
* @param <TItem> the value type
@@ -76,8 +75,7 @@ public static <TItem> Bson eq(@Nullable final TItem value) {
7675
}
7776

7877
/**
79-
* Creates a filter that matches all documents where the value of the field name equals the specified value. Note that this doesn't
80-
* actually generate a $eq operator, as the query language doesn't require it.
78+
* Creates a filter that matches all documents where the value of the field name equals the specified value.
8179
*
8280
* @param fieldName the field name
8381
* @param value the value, which may be null
@@ -86,7 +84,7 @@ public static <TItem> Bson eq(@Nullable final TItem value) {
8684
* @mongodb.driver.manual reference/operator/query/eq $eq
8785
*/
8886
public static <TItem> Bson eq(final String fieldName, @Nullable final TItem value) {
89-
return new SimpleEncodingFilter<>(fieldName, value);
87+
return new OperatorFilter<>("$eq", fieldName, value);
9088
}
9189

9290
/**

driver-core/src/main/com/mongodb/client/model/Projections.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@
1616

1717
package com.mongodb.client.model;
1818

19+
import com.mongodb.client.model.search.FieldSearchPath;
1920
import com.mongodb.client.model.search.SearchCollector;
2021
import com.mongodb.client.model.search.SearchCount;
2122
import com.mongodb.client.model.search.SearchOperator;
2223
import com.mongodb.client.model.search.SearchOptions;
24+
import com.mongodb.client.model.search.VectorSearchOptions;
2325
import org.bson.BsonArray;
2426
import org.bson.BsonDocument;
2527
import org.bson.BsonInt32;
@@ -196,6 +198,20 @@ public static Bson metaSearchScore(final String fieldName) {
196198
return meta(fieldName, "searchScore");
197199
}
198200

201+
/**
202+
* Creates a projection to the given field name of the vectorSearchScore,
203+
* for use with {@link Aggregates#vectorSearch(FieldSearchPath, Iterable, String, long, long, VectorSearchOptions)}.
204+
* Calling this method is equivalent to calling {@link #meta(String, String)} with {@code "vectorSearchScore"} as the second argument.
205+
*
206+
* @param fieldName the field name
207+
* @return the projection
208+
* @mongodb.atlas.manual atlas-search/scoring/ Scoring
209+
* @since 4.7
210+
*/
211+
public static Bson metaVectorSearchScore(final String fieldName) {
212+
return meta(fieldName, "vectorSearchScore");
213+
}
214+
199215
/**
200216
* Creates a projection to the given field name of the searchHighlights,
201217
* for use with {@link Aggregates#search(SearchOperator, SearchOptions)} / {@link Aggregates#search(SearchCollector, SearchOptions)}.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright 2008-present MongoDB, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.mongodb.client.model.search;
17+
18+
import com.mongodb.annotations.Immutable;
19+
import com.mongodb.internal.client.model.AbstractConstructibleBson;
20+
import org.bson.BsonDocument;
21+
import org.bson.Document;
22+
import org.bson.conversions.Bson;
23+
24+
import static com.mongodb.assertions.Assertions.notNull;
25+
26+
final class VectorSearchConstructibleBson extends AbstractConstructibleBson<VectorSearchConstructibleBson> implements VectorSearchOptions {
27+
/**
28+
* An {@linkplain Immutable immutable} {@link BsonDocument#isEmpty() empty} instance.
29+
*/
30+
static final VectorSearchConstructibleBson EMPTY_IMMUTABLE = new VectorSearchConstructibleBson(AbstractConstructibleBson.EMPTY_IMMUTABLE);
31+
32+
VectorSearchConstructibleBson(final Bson base) {
33+
super(base);
34+
}
35+
36+
private VectorSearchConstructibleBson(final Bson base, final Document appended) {
37+
super(base, appended);
38+
}
39+
40+
@Override
41+
protected VectorSearchConstructibleBson newSelf(final Bson base, final Document appended) {
42+
return new VectorSearchConstructibleBson(base, appended);
43+
}
44+
45+
@Override
46+
public VectorSearchOptions filter(final Bson filter) {
47+
return newAppended("filter", notNull("name", filter));
48+
}
49+
50+
@Override
51+
public VectorSearchOptions option(final String name, final Object value) {
52+
return newAppended(notNull("name", name), notNull("value", value));
53+
}
54+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright 2008-present MongoDB, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.mongodb.client.model.search;
17+
18+
import com.mongodb.annotations.Beta;
19+
import com.mongodb.annotations.Sealed;
20+
import com.mongodb.client.model.Aggregates;
21+
import org.bson.conversions.Bson;
22+
23+
/**
24+
* Represents optional fields of the {@code $vectorSearch} pipeline stage of an aggregation pipeline.
25+
*
26+
* @see Aggregates#vectorSearch(FieldSearchPath, Iterable, String, long, long, VectorSearchOptions)
27+
* @mongodb.atlas.manual / @mongodb.driver.dochub VAKOTODO
28+
* @mongodb.server.release 7.1
29+
* @since 4.11
30+
*/
31+
@Sealed
32+
@Beta(Beta.Reason.SERVER)
33+
public interface VectorSearchOptions extends Bson {
34+
/**
35+
* Creates a new {@link VectorSearchOptions} with the filter specified.
36+
*
37+
* @param filter VAKOTODO
38+
* @return A new {@link VectorSearchOptions}.
39+
*/
40+
VectorSearchOptions filter(Bson filter);
41+
42+
/**
43+
* Creates a new {@link VectorSearchOptions} with the specified option in situations when there is no builder method
44+
* that better satisfies your needs.
45+
* This method cannot be used to validate the syntax.
46+
* <p>
47+
* <i>Example</i><br>
48+
* The following code creates two functionally equivalent {@link VectorSearchOptions} objects,
49+
* though they may not be {@linkplain Object#equals(Object) equal}.
50+
* <pre>{@code
51+
* VectorSearchOptions options1 = VectorSearchOptions.vectorSearchOptions()
52+
* .filter(Filters.lt("fieldName", 1));
53+
* VectorSearchOptions options2 = VectorSearchOptions.vectorSearchOptions()
54+
* .option("filter", Filters.lt("fieldName", 1));
55+
* }</pre>
56+
*
57+
* @param name The option name.
58+
* @param value The option value.
59+
* @return A new {@link VectorSearchOptions}.
60+
*/
61+
VectorSearchOptions option(String name, Object value);
62+
63+
/**
64+
* Returns {@link VectorSearchOptions} that represents server defaults.
65+
*
66+
* @return {@link VectorSearchOptions} that represents server defaults.
67+
*/
68+
static VectorSearchOptions vectorSearchOptions() {
69+
return VectorSearchConstructibleBson.EMPTY_IMMUTABLE;
70+
}
71+
}

driver-core/src/main/com/mongodb/client/model/search/package-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
*
2626
* @see com.mongodb.client.model.Aggregates#search(SearchOperator, SearchOptions)
2727
* @see com.mongodb.client.model.Aggregates#search(SearchCollector, SearchOptions)
28+
* @see com.mongodb.client.model.Aggregates#vectorSearch(FieldSearchPath, java.lang.Iterable, java.lang.String, long, long, VectorSearchOptions)
2829
* @mongodb.atlas.manual atlas-search/ Atlas Search
2930
* @mongodb.atlas.manual atlas-search/query-syntax/ Atlas Search aggregation pipeline stages
3031
* @since 4.7

driver-core/src/test/functional/com/mongodb/client/model/search/AggregatesSearchIntegrationTest.java

Lines changed: 121 additions & 14 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)