diff --git a/source/atlas-vector-search.txt b/source/atlas-vector-search.txt index cf6585fe..adc1e42b 100644 --- a/source/atlas-vector-search.txt +++ b/source/atlas-vector-search.txt @@ -2,4 +2,134 @@ ================================ Run an Atlas Vector Search Query -================================ \ No newline at end of file +================================ + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: full text, text analyzer, meta, pipeline, scoring, Lucene, AI, artificial intelligence, code example, semantic, nearest + :description: Learn about how to use Atlas Vector Search in the {+driver-short+}. + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +Overview +-------- + +In this guide, you can learn how to use the {+driver-short+} to perform +:atlas:`Atlas Vector Search ` +queries. The ``Aggregates`` builders class provides the +``vectorSearch()`` helper method, which you can use to +create a :atlas:`$vectorSearch ` +pipeline stage. + +.. important:: Feature Compatibility + + To learn which versions of MongoDB Atlas support this feature, see + :atlas:`Limitations ` + in the MongoDB Atlas documentation. + +Perform a Vector Search +----------------------- + +Before you can perform Atlas Vector Search queries, you must create an Atlas Vector Search +index on your collection. To learn how to programmatically create a +vector search index, see the :ref:`kotlin-sync-search-avs-indexes` guide. + +Then, you can run an Atlas Vector Search query by using the +``vectorSearch()`` method in an aggregation pipeline. This +method accepts the following parameters: + +- ``path``: The field to search +- ``queryVector``: The vector embedding that represents your search query +- ``indexName``: The name of the Atlas Vector Search index to use +- ``limit``: The maximum number of results to return +- ``options``: *(Optional)* A set of options that you can use to configure the + vector search query + +Basic Vector Search Example +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This example runs an Atlas Vector Search query that performs +the following actions: + +- Queries the ``plot_embedding`` vector field. +- Limits the results to ``5`` documents. +- Specifies an Approximate Nearest Neighbor (ANN) vector search that considers + ``150`` candidates. To learn more about ANN searches, see :atlas:`ANN Search ` + in the MongoDB Atlas documentation. + +.. io-code-block:: + + .. input:: /includes/vector-search.kt + :start-after: start-vs + :end-before: end-vs + :language: kotlin + :dedent: + + .. output:: + :visible: false + + {"title": "Berserk: The Golden Age Arc I - The Egg of the King"} + {"title": "Rollerball"} + {"title": "After Life"} + {"title": "What Women Want"} + {"title": "Truth About Demons"} + +.. tip:: Query Vector Type + + The preceding example creates an instance of ``BinaryVector`` to + serve as the query vector, but you can also create a ``List`` of + ``Double`` instances. However, we recommend that you use the + ``BinaryVector`` type to improve storage efficiency. + +Vector Search Score Example +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following example shows how to run same vector search +query as the preceding example and print the documents' vector search +meta-score. This score represents the relevance of each +document to the query vector: + +.. io-code-block:: + + .. input:: /includes/vector-search.kt + :start-after: start-vs-score + :end-before: end-vs-score + :language: kotlin + :dedent: + + .. output:: + :visible: false + + Title: Berserk: The Golden Age Arc I - The Egg of the King, Score: 0.49899211525917053 + Title: Rollerball, Score: 0.4976102113723755 + Title: After Life, Score: 0.4965665936470032 + Title: What Women Want, Score: 0.49622756242752075 + Title: Truth About Demons, Score: 0.49614521861076355 + +.. tip:: Vector Search Tutorials + + To view more tutorials that show how to run Atlas Vector Search queries, + see the :atlas:`Atlas Vector Search Tutorials ` + in the MongoDB Atlas documentation. + +API Documentation +----------------- + +To learn more about the methods and types mentioned in this +guide, see the following API documentation: + +- `Aggregates.vectorSearch() + <{+core-api+}/client/model/Aggregates.html#vectorSearch(com.mongodb.client.model.search.FieldSearchPath,java.lang.Iterable,java.lang.String,long,com.mongodb.client.model.search.VectorSearchOptions)>`__ + +- `VectorSearchOptions + <{+core-api+}/client/model/search/VectorSearchOptions.html>`__ + +- `Projections.metaVectorSearchScore() + <{+core-api+}/client/model/Projections.html#metaVectorSearchScore(java.lang.String)>`__ diff --git a/source/includes/vector-search.kt b/source/includes/vector-search.kt new file mode 100644 index 00000000..78036153 --- /dev/null +++ b/source/includes/vector-search.kt @@ -0,0 +1,84 @@ +package org.example + +import com.mongodb.ConnectionString +import com.mongodb.kotlin.client.MongoClient +import com.mongodb.MongoClientSettings +import com.mongodb.client.model.Aggregates.project +import com.mongodb.client.model.Aggregates.vectorSearch +import com.mongodb.client.model.search.FieldSearchPath +import com.mongodb.client.model.Projections +import com.mongodb.client.model.search.SearchPath.fieldPath +import org.bson.BinaryVector +import org.bson.conversions.Bson +import com.mongodb.client.model.search.VectorSearchOptions.approximateVectorSearchOptions +import org.bson.Document + +fun main() { + val uri = "" + + val settings = MongoClientSettings.builder() + .applyConnectionString(ConnectionString(uri)) + .retryWrites(true) + .build() + + val mongoClient = MongoClient.create(settings) + val database = mongoClient.getDatabase("sample_mflix") + val collection = database.getCollection("embedded_movies") + + // start-vs + val vectorValues = FloatArray(1536) { i -> (i % 10).toFloat() * 0.1f } + val queryVector = BinaryVector.floatVector(vectorValues) + val indexName = "" + + // Specifies the path of the field to search + val fieldSearchPath: FieldSearchPath = fieldPath("plot_embedding") + + // Creates the vector search pipeline stage with a limit and numCandidates + val pipeline: List = listOf( + vectorSearch( + fieldSearchPath, + queryVector, + indexName, + 5L, + approximateVectorSearchOptions(150) + ), + project( + Projections.fields( + Projections.excludeId(), + Projections.include("title") + ) + ) + ) + + val results = collection.aggregate(pipeline) + + results.forEach { doc -> + println(doc.toJson()) + } + // end-vs + + // start-vs-score + val pipeline: List = listOf( + vectorSearch( + fieldSearchPath, + queryVector, + indexName, + 5L, + approximateVectorSearchOptions(150) + ), + project( + Projections.fields( + Projections.excludeId(), + Projections.include("title"), + Projections.metaVectorSearchScore("score") + ) + ) + ) + + val results = collection.aggregate(pipeline) + + results.forEach { doc -> + println("Title: ${doc.getString("title")}, Score: ${doc.getDouble("score")}") + } + // end-vs-score +}