Skip to content

Commit 3affecb

Browse files
committed
Add Vector Search tutorial
1 parent 8220fcb commit 3affecb

File tree

2 files changed

+187
-1
lines changed

2 files changed

+187
-1
lines changed

docs/en/cookbook/vector-search.rst

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
Vector Search Cookbook
2+
======================
3+
4+
This tutorial demonstrates how to use `MongoDB Atlas Vector Search`_ with Doctrine
5+
MongoDB ODM. Vector search enables semantic queries over vector embeddings,
6+
which are typically generated by an embedding system.
7+
8+
Step 1: Generate Vector Embeddings
9+
----------------------------------
10+
11+
Before storing data, you need to generate vector embeddings for your documents.
12+
You can use an embedding system such as Symfony AI to convert text or other
13+
data into a ``float[]`` vector.
14+
15+
Example using `Voyage AI`_ and `Symfony AI`_:
16+
17+
.. code-block:: php
18+
19+
use Symfony\AI\Platform\Bridge\Voyage\PlatformFactory;
20+
21+
$platform = PlatformFactory::create(getenv('VOYAGE_API_KEY'));
22+
$vectors = $platform->invoke('voyage-3', <<<'TEXT'
23+
Once upon a time, there was a country called Japan. It was a beautiful country with a lot of mountains and rivers.
24+
The people of Japan were very kind and hardworking. They loved their country very much and took care of it. The
25+
country was very peaceful and prosperous. The people lived happily ever after.
26+
TEXT)->asVectors();
27+
28+
Step 2: Define the Model
29+
------------------------
30+
31+
Annotate your document with `#[VectorSearchIndex] attribute <reference/attributes#vector_search_index>`_
32+
and define a vector field of type ``float[]``.
33+
The number of dimensions must match the embedding vector size (e.g., 1024).
34+
The similarity metric can be either cosine, euclidean or dotProduct; they all
35+
return the same result because Voyage AI uses normalized vectors to length 1.
36+
37+
.. code-block:: php
38+
39+
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
40+
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
41+
use Doctrine\ODM\MongoDB\Types\Type;
42+
use Symfony\AI\Platform\Vector\Vector;
43+
44+
#[ODM\Document]
45+
#[ODM\VectorSearchIndex(
46+
fields: [
47+
[
48+
'type' => 'vector',
49+
'path' => 'voyage3Vector',
50+
'numDimensions' => 1024,
51+
'similarity' => ClassMetadata::VECTOR_SIMILARITY_DOT_PRODUCT,
52+
],
53+
[
54+
'type' => 'filter',
55+
'path' => 'published',
56+
],
57+
],
58+
name: 'default',
59+
)]
60+
class Guide
61+
{
62+
#[ODM\Id]
63+
public ?string $id = null;
64+
65+
#[ODM\Field]
66+
public bool $published = false;
67+
68+
#[ODM\Field]
69+
public ?string $content = null;
70+
71+
/** @var list<float>|null Embedding vector created from $content */
72+
#[ODM\Field(type: Type::COLLECTION)]
73+
public ?array $voyage3Vector = null;
74+
75+
/** @param list<float>|Vector $vector */
76+
public function setVoyage3Vector(array|Vector $vector): void
77+
{
78+
if ($vector instanceof Vector) {
79+
if ($vector->getDimensions() !== 1024) {
80+
throw new InvalidArgumentException('The embedding vector must have 1024 dimensions.');
81+
}
82+
83+
$vector = $vector->getData();
84+
}
85+
86+
if (! count($vector) === 1024) {
87+
throw new InvalidArgumentException('The embedding vector must have 1024 dimensions.');
88+
}
89+
90+
$this->voyage3Vector = $vector;
91+
}
92+
}
93+
94+
Step 3: Create the Collection and Insert Documents
95+
--------------------------------------------------
96+
97+
Use the ``SchemaManager`` to create the collection and insert documents with vector embeddings.
98+
99+
.. code-block:: php
100+
101+
$schemaManager = $dm->getSchemaManager();
102+
$schemaManager->createDocumentCollection(Guide::class);
103+
104+
Insert documents:
105+
106+
.. code-block:: php
107+
108+
$doc1 = new Guide();
109+
$doc1->published = true;
110+
$doc1->content = 'First document';
111+
112+
$doc2 = new Guide();
113+
$doc2->published = false;
114+
115+
$dm->persist($doc1);
116+
$dm->persist($doc2);
117+
$dm->flush();
118+
119+
The vector values of each document can be set later, typically using an asynchronous process:
120+
121+
.. code-block:: php
122+
123+
$vector1 = $embeddingPlatform->invoke($doc1->content)->asVectors()[0];
124+
$doc1->setVoyage3Vector($vector1);
125+
126+
$vector2 = $embeddingPlatform->invoke($doc2->content)->asVectors()[0];
127+
$doc2->setVoyage3Vector($vector2);
128+
129+
$dm->flush();
130+
131+
132+
Step 4: Create the Vector Search Index
133+
--------------------------------------
134+
135+
When updating documents, the vector search index is asynchronously updated by
136+
MongoDB Atlas. You have to wait a few seconds before the changes are reflected
137+
in search results.
138+
139+
.. code-block:: php
140+
141+
$schemaManager->createDocumentSearchIndexes(Guide::class);
142+
143+
144+
If the vector search index created after inserting documents, the index is
145+
marked as "READY" when all existing documents are indexed. You can wait for
146+
the index to be ready using the following code:
147+
148+
.. code-block:: php
149+
150+
$schemaManager->waitForSearchIndexes([Guide::class]);
151+
152+
Step 5: Run a Vector Search Aggregation
153+
---------------------------------------
154+
155+
Use the aggregation builder to run a vector search query:
156+
157+
.. code-block:: php
158+
159+
$results = $dm->createAggregationBuilder(Guide::class)
160+
->vectorSearch()
161+
->index('default')
162+
->path('voyage3Vector')
163+
->queryVector($vector)
164+
->filter($qb->expr()->field('published')->equals(true))
165+
->numCandidates(10)
166+
->limit(10)
167+
->set()
168+
->field('score')
169+
->expression(['$meta' => 'vectorSearchScore'])
170+
->getAggregation()->execute()->toArray();
171+
172+
var_dump($results);
173+
174+
Notes
175+
-----
176+
- Vector embeddings should be generated using a reliable embedding system
177+
- The vector field must be of type ``float[]``, ``int[]`` or ``bool[]``, it
178+
must match with the embedding vector type and dimensions.
179+
- The ``#[VectorSearchIndex]`` annotation configures the index for vector search
180+
- Use the aggregation builder's ``vectorSearch`` stage to query for similar vectors.
181+
- Doctrine ODM 2.13+ is required for vector search support.
182+
183+
184+
.. _`MongoDB Atlas Vector Search`: <https://www.mongodb.com/docs/atlas/atlas-vector-search/>
185+
.. _`Voyage AI`: https://www.voyageai.com/
186+
.. _`Symfony AI`: https://symfony.com/ai

docs/en/reference/aggregation-stage-reference.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -803,7 +803,7 @@ field or fields which must be covered by an Atlas Vector Search index.
803803
``$vectorSearch`` must be the first stage in the aggregation pipeline.
804804

805805
.. note::
806-
A `Search index <https://www.mongodb.com/docs/atlas/atlas-search/>`_
806+
A `Vector Search index <https://www.mongodb.com/docs/atlas/atlas-vector-search/>`_
807807
is required for this stage. See the `#[VectorSearchIndex] attribute </reference/attributes.html#vector_search_index>`_
808808
for details on how to define it.
809809

0 commit comments

Comments
 (0)