Create and query an autoEmbed index¶
Once an embedding engine is connected, the workflow is the same whichever engine you chose. You create a Vector Search index with an autoEmbed field, wait for the initial build, and query with plain text.
Note
This page uses the nomic-embed-text model from the Ollama setup. Substitute your own model name if you connected a different engine.
Before you begin¶
Make sure that:
- Automatic embedding is enabled in
Percona Search for MongoDB, and the embedding engine is reachable from themongothost. - The model you plan to use exists in
embedding-service-configs.yml. - The collection contains the text field you want to search.
If mongot skipped your model at startup, fix that before you create an index. See Troubleshoot automatic embedding.
Procedure¶
To create and query an autoEmbed index, do the following:
-
Create sample data.
movies collection
use mydb db.movies.insertMany([ { title: "The Martian", plot: "An astronaut becomes stranded on Mars and must use his ingenuity to survive until rescue" }, { title: "Finding Nemo", plot: "A clownfish father crosses the ocean to find his son who was captured by a scuba diver" }, { title: "The Godfather", plot: "The aging patriarch of an organized crime dynasty transfers control of his empire to his reluctant son" } ]); -
Create the index.
Use the following syntax:
db.<collection>.createSearchIndex( "<index-name>", "vectorSearch", { fields: [ { type: "autoEmbed", modality: "text", path: "<field-to-embed>", model: "<model-name>" } ] } );Replace the placeholders with your own values:
Placeholder Value <collection>The collection holding the documents you want to search. <index-name>A name for the index. You reference it later in $vectorSearch.<field-to-embed>The text field that mongotembeds. Use dot notation for a nested field.<model-name>A modelNamefrom the model catalog.Note
The
modelvalue must match amodelNamedefined inembedding-service-configs.yml. You don’t need to setnumDimensions, becausemongotresolves the dimension from the model’soutputDimensionsin the catalog.Vector search index for the plot field
db.movies.createSearchIndex( "plot_semantic", "vectorSearch", { fields: [ { type: "autoEmbed", modality: "text", path: "plot", model: "nomic-embed-text" } ] } );To filter results before the vector search runs, add a
filterfield alongside theautoEmbedfield. For the full set of index fields, see How to Index Fields for Vector Search in the MongoDB documentation. -
Check the index status.
db.movies.getSearchIndexes("plot_semantic");The index stays in a build state while embeddings are generated, moving from
BUILDINGtoREADY. On a large collection this takes time, and the work happens on your embedding engine.Wait until the index is ready before you run vector search queries.
What happens during the initial build
mongot:- Scans documents that contain the indexed field.
- Sends the field value to the configured embedding provider.
- Receives the generated vector.
- Stores the generated vectors in a dedicated internal collection on
mongod. - Builds the Vector Search index.
-
Run a semantic query.
Pass plain text to
$vectorSearch.mongotembeds the query text with the same model named in the index:db.<collection>.aggregate([ { $vectorSearch: { index: "<index-name>", path: "<field-to-embed>", query: { text: "<search-text>" }, numCandidates: <number-of-candidates>, limit: <number-of-results> } }, { $project: { _id: 0, <field1>: 1, <field2>: 1, score: { $meta: "vectorSearchScore" } } } ]);Replace the placeholders with your own values:
Placeholder Value <collection>The collection holding the documents you want to search. <index-name>The name of the vector search index you created. <field-to-embed>The text field that mongotembeds. Use dot notation for a nested field.<search-text>The plain text query to search for. <number-of-candidates>The number of candidates to consider during the search. Set it higher than <number-of-results>.<number-of-results>The number of top results to return. <field1>,<field2>The fields to include in the query result. Semantic query with plain text
db.movies.aggregate([ { $vectorSearch: { index: "plot_semantic", path: "plot", query: { text: "space exploration survival mission" }, numCandidates: 10, limit: 3 } }, { $project: { _id: 0, title: 1, score: { $meta: "vectorSearchScore" } } } ]);The output is similar to the following:
[ { "title": "The Martian", "score": 0.82 } ]What happens at query time
mongotgenerates an embedding for the query text, applying the model’squeryPrefixif one is configured, then compares that vector against the vectors in the index to find the closest matches.The score comes from
{ $meta: "vectorSearchScore" }and is calculated at query time. A higher score means a closer match under the configured similarity function.If you don’t specify
modelin$vectorSearch,mongotuses the model named in the index. You can override it, but the model you name must be compatible with the one used at index time. Embeddings from unrelated models aren’t comparable, so an incompatible override returns results that look plausible and aren’t. -
Insert new documents.
mongotembeds new and changed documents as they are written, using change streams, so there is no reindexing to schedule.Embedding a newly inserted document
db.movies.insertOne({ title: "Apollo 13", category: "drama", plot: "Astronauts work with mission control to survive a damaged spacecraft and return safely to Earth" });When the indexed text changes,
mongotgenerates a new embedding. When a document is deleted, its generated embedding is removed. -
Monitor embedding requests.
Use the
mongotmetrics endpoint to watch embedding traffic by provider. For OpenAI-compatible engines, filter on theOPENAI_COMPATIBLEprovider:curl -s localhost:9946/metrics | grep 'provider="OPENAI_COMPATIBLE"'The following metrics are useful for monitoring embedding requests:
mongot_embeddingClient_inputTokenDistribution_*tracks input token usage by model and by workload. The workload is one ofCOLLECTION_SCAN,CHANGE_STREAM, orQUERY.mongot_embeddingClient_invalidRequestCountercounts embedding requests rejected as invalid.
These metrics can help you monitor embedding usage, understand which workloads generate the most traffic, and identify rejected requests.