Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@
import com.mongodb.client.model.search.SearchOperator;
import com.mongodb.client.model.search.SearchOptions;
import com.mongodb.client.model.search.TextVectorSearchQuery;
import com.mongodb.client.model.search.VectorSearchNestedOptions;
import com.mongodb.client.model.search.VectorSearchOptions;
import com.mongodb.client.model.search.VectorSearchQuery;
import com.mongodb.client.model.search.VectorSearchScoreMode;
import com.mongodb.lang.Nullable;
import org.bson.BsonArray;
import org.bson.BsonBoolean;
Expand Down Expand Up @@ -952,6 +954,13 @@ public static Bson searchMeta(final SearchCollector collector, final SearchOptio
* You may use the {@code $meta: "vectorSearchScore"} expression, e.g., via {@link Projections#metaVectorSearchScore(String)},
* to extract the relevance score assigned to each found document.
*
* <p>The {@code path} may reference a nested (embedded) field using dot notation, in which case the
* search is performed against embeddings in the embedded documents. For a nested search, use
* {@link VectorSearchOptions#filter(Bson)} to filter the leaf (embedded) documents,
* {@link VectorSearchOptions#parentFilter(Bson)} to filter the parent documents, and
* {@link VectorSearchOptions#nestedOptions(VectorSearchNestedOptions)} (e.g.
* {@link VectorSearchNestedOptions#scoreMode(VectorSearchScoreMode)}) to control score aggregation.</p>
*
* @param queryVector The query vector. The number of dimensions must match that of the {@code index}.
* @param path The field to be searched.
* @param index The name of the index to use.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ public interface SearchOptions extends Bson {
* @param option The counting option.
* @return A new {@link SearchOptions}.
*/
@Beta({Reason.CLIENT, Reason.SERVER})

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note the whole SearchOptions file is annotated @Beta(Reason.CLIENT)

SearchOptions count(SearchCount option);

/**
Expand All @@ -64,7 +63,6 @@ public interface SearchOptions extends Bson {
* @return A new {@link SearchOptions}.
* @mongodb.atlas.manual atlas-search/return-stored-source/ Return stored source fields
*/
@Beta({Reason.CLIENT, Reason.SERVER})
SearchOptions returnStoredSource(boolean returnStoredSource);

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ public VectorSearchOptions filter(final Bson filter) {
return newAppended("filter", notNull("filter", filter));
}

@Override
public VectorSearchOptions parentFilter(final Bson parentFilter) {
return newAppended("parentFilter", notNull("parentFilter", parentFilter));
}

@Override
public VectorSearchOptions nestedOptions(final VectorSearchNestedOptions nestedOptions) {
return newAppended("nestedOptions", notNull("nestedOptions", nestedOptions));
}

@Override
public VectorSearchOptions returnStoredSource(final boolean returnStoredSource) {
return newAppended("returnStoredSource", new BsonBoolean(returnStoredSource));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright 2008-present MongoDB, Inc.
*
* 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.
*/
package com.mongodb.client.model.search;

import com.mongodb.annotations.Immutable;
import com.mongodb.internal.client.model.AbstractConstructibleBson;
import org.bson.BsonDocument;
import org.bson.Document;
import org.bson.conversions.Bson;

import static com.mongodb.assertions.Assertions.notNull;

final class VectorSearchNestedConstructibleBson extends AbstractConstructibleBson<VectorSearchNestedConstructibleBson>
implements VectorSearchNestedOptions {
/**
* An {@linkplain Immutable immutable} {@link BsonDocument#isEmpty() empty} instance.
*/
static final VectorSearchNestedConstructibleBson EMPTY_IMMUTABLE =
new VectorSearchNestedConstructibleBson(AbstractConstructibleBson.EMPTY_IMMUTABLE);

VectorSearchNestedConstructibleBson(final Bson base) {
super(base);
}

private VectorSearchNestedConstructibleBson(final Bson base, final Document appended) {
super(base, appended);
}

@Override
protected VectorSearchNestedConstructibleBson newSelf(final Bson base, final Document appended) {
return new VectorSearchNestedConstructibleBson(base, appended);
}

@Override
public VectorSearchNestedOptions scoreMode(final VectorSearchScoreMode scoreMode) {
return newAppended("scoreMode", notNull("scoreMode", scoreMode).getValue());
}

@Override
public VectorSearchNestedOptions option(final String name, final Object value) {
return newAppended(notNull("name", name), notNull("value", value));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright 2008-present MongoDB, Inc.
*
* 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.
*/
package com.mongodb.client.model.search;

import com.mongodb.annotations.Sealed;
import org.bson.conversions.Bson;

/**
* Represents the optional {@code nestedOptions} sub-document of the {@code $vectorSearch} pipeline stage,
* used when searching against arrays of embeddings within nested (embedded) documents.
*
* @see VectorSearchOptions#nestedOptions(VectorSearchNestedOptions)
* @mongodb.atlas.manual atlas-vector-search/vector-search-stage/ $vectorSearch
* @mongodb.server.release 8.3
* @since 5.10
*/
@Sealed
public interface VectorSearchNestedOptions extends Bson {
/**
* Creates a new {@link VectorSearchNestedOptions} with the score aggregation mode specified.
*
* @param scoreMode The score aggregation mode for the matching embeddings within a document.
* @return A new {@link VectorSearchNestedOptions}.
*/
VectorSearchNestedOptions scoreMode(VectorSearchScoreMode scoreMode);

/**
* Creates a new {@link VectorSearchNestedOptions} with the specified option in situations when there is no
* builder method that better satisfies your needs.
* This method cannot be used to validate the syntax.
* <p>
* <i>Example</i><br>
* The following code creates two functionally equivalent {@link VectorSearchNestedOptions} objects,
* though they may not be {@linkplain Object#equals(Object) equal}.
* <pre>{@code
* VectorSearchNestedOptions options1 = VectorSearchNestedOptions.vectorSearchNestedOptions()
* .scoreMode(VectorSearchScoreMode.AVG);
* VectorSearchNestedOptions options2 = VectorSearchNestedOptions.vectorSearchNestedOptions()
* .option("scoreMode", "avg");
* }</pre>
*
* @param name The option name.
* @param value The option value.
* @return A new {@link VectorSearchNestedOptions}.
*/
VectorSearchNestedOptions option(String name, Object value);

/**
* Returns {@link VectorSearchNestedOptions} that represents server defaults.
*
* @return {@link VectorSearchNestedOptions} that represents server defaults.
*/
static VectorSearchNestedOptions vectorSearchNestedOptions() {
return VectorSearchNestedConstructibleBson.EMPTY_IMMUTABLE;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
/**
* Represents optional fields of the {@code $vectorSearch} pipeline stage of an aggregation pipeline.
*
* <p>This includes options for searching against nested (embedded) embeddings and arrays of embeddings,
* via {@link #parentFilter(Bson)} and {@link #nestedOptions(VectorSearchNestedOptions)}.</p>
*
* @see Aggregates#vectorSearch(FieldSearchPath, Iterable, String, long, VectorSearchOptions)
* @mongodb.atlas.manual atlas-vector-search/vector-search-stage/ $vectorSearch
* @mongodb.server.release 6.0.11
Expand All @@ -41,6 +44,41 @@ public interface VectorSearchOptions extends Bson {
*/
VectorSearchOptions filter(Bson filter);

/**
* Creates a new {@link VectorSearchOptions} with the parent filter specified.
*
* <p>Applies only when searching against a nested (embedded) field: this filter is applied to the
* parent (root) documents, while {@link #filter(Bson)} is applied to the leaf (embedded) documents.
* For a non-nested search, use {@link #filter(Bson)} instead.</p>
* <p>Unlike some other MongoDB drivers, the Java driver does not automatically re-route a top-level
* {@link #filter(Bson)} to {@code parentFilter} based on the path: you must call
* {@link #parentFilter(Bson)} explicitly to specify a parent (root-level) filter for a nested search.</p>
*
* @param parentFilter A filter applied to the parent documents of a nested {@code $vectorSearch}.
* One may use {@link Filters} to create this filter, though not all filters may be supported.
* See the MongoDB documentation for the list of supported filters.
* @return A new {@link VectorSearchOptions}.
* @mongodb.atlas.manual atlas-vector-search/vector-search-stage/ $vectorSearch
* @mongodb.server.release 8.3
* @since 5.10
*/
VectorSearchOptions parentFilter(Bson parentFilter);

/**
* Creates a new {@link VectorSearchOptions} with the {@code nestedOptions} specified.
*
* <p>Applies only when searching against arrays of embeddings within nested (embedded) documents;
* for example it controls how the scores of the individual matching embeddings within a document are
* aggregated (see {@link VectorSearchNestedOptions#scoreMode(VectorSearchScoreMode)}).</p>
*
* @param nestedOptions The options for a nested (embedded) {@code $vectorSearch}.
* @return A new {@link VectorSearchOptions}.
* @mongodb.atlas.manual atlas-vector-search/vector-search-stage/ $vectorSearch
* @mongodb.server.release 8.3
* @since 5.10
*/
VectorSearchOptions nestedOptions(VectorSearchNestedOptions nestedOptions);

/**
* Creates a new {@link VectorSearchOptions} that instructs to return only stored source fields.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright 2008-present MongoDB, Inc.
*
* 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.
*/
package com.mongodb.client.model.search;

/**
* The score aggregation mode for a {@code $vectorSearch} against arrays of embeddings in nested (embedded) documents.
*
* <p>If {@code scoreMode} is not specified, the server default is {@link #MAX} ({@code "max"}).</p>
*
* @see VectorSearchNestedOptions#scoreMode(VectorSearchScoreMode)
* @mongodb.atlas.manual atlas-vector-search/vector-search-stage/ $vectorSearch
* @mongodb.server.release 8.3
* @since 5.10
*/
public enum VectorSearchScoreMode {
/**
* Use the average of the scores of the matching embeddings within a document.
*/
AVG("avg"),

/**
* Use the maximum of the scores of the matching embeddings within a document.
*/
MAX("max");

private final String value;

VectorSearchScoreMode(final String value) {
this.value = value;
}

/**
* Returns the value used by the server for this score mode.
*
* @return the server value ({@code "avg"} or {@code "max"}).
* @since 5.10
*/
public String getValue() {
return value;
}
}
Loading