Skip to content

Commit 7da04fe

Browse files
authored
DOC-738 | Vector index reference docs (#700)
* Initial reference docs about the vector index * HTTP API docs and refinements * Version remark, OpenAPI minItems/maxItems and fix a type * inBackground and parallelism are supported * Review feedback, address cosine metric issue, reword inBackground, add parallelism * Remove leftover line * Add internal links to release notes * Vector indexes not supported by web interface in v3.12.5
1 parent d640e84 commit 7da04fe

File tree

28 files changed

+1287
-140
lines changed

28 files changed

+1287
-140
lines changed

site/content/3.12/about-arangodb/features/core.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ available from v3.12.5 onward.
158158
{{% /comment %}}
159159

160160
{{% comment %}} Experimental feature
161-
- [**Vector search**](#TODO):
161+
- [**Vector search**](../../index-and-search/indexing/working-with-indexes/vector-indexes.md):
162162
Find items with similar properties by comparing vector embeddings generated by
163163
machine learning models.
164164
{{% /comment %}}
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
---
2+
title: Vector search functions in AQL
3+
menuTitle: Vector
4+
weight: 60
5+
description: >-
6+
The functions for vector search let you quickly find semantically similar
7+
documents utilizing indexed vector embeddings
8+
---
9+
<small>Introduced in: v3.12.4</small>
10+
11+
To use vector search, you need to have vector embeddings stored in documents
12+
and the attribute that stores them needs to be indexed by a
13+
[vector index](../../index-and-search/indexing/working-with-indexes/vector-indexes.md).
14+
15+
You can calculate vector embeddings using [ArangoDB's GraphML](../../data-science/arangographml/_index.md)
16+
capabilities (available in ArangoGraph) or using external tools.
17+
18+
{{< warning >}}
19+
The vector index is an experimental feature that you need to enable for the
20+
ArangoDB server with the `--experimental-vector-index` startup option.
21+
Once enabled for a deployment, it cannot be disabled anymore because it
22+
permanently changes how the data is managed by the RocksDB storage engine
23+
(it adds an additional column family).
24+
25+
To restore a dump that contains vector indexes, the `--experimental-vector-index`
26+
startup option needs to be enabled on the deployment you want to restore to.
27+
{{< /warning >}}
28+
29+
## Vector similarity functions
30+
31+
In order to utilize a vector index, you need to do the following in an AQL query:
32+
33+
- Use one of the following vector similarity functions in a query.
34+
- `SORT` by the similarity so that the most similar documents come first.
35+
- Specify the maximum number of documents to retrieve with a `LIMIT` operation.
36+
37+
As a result, you get up to the specified number of documents whose vector embeddings
38+
are the most similar to the reference vector embedding you provided in the query,
39+
as approximated by the vector index.
40+
41+
Example:
42+
43+
```aql
44+
FOR doc IN coll
45+
SORT APPROX_NEAR_COSINE(doc.vector, @q) DESC
46+
LIMIT 5
47+
RETURN doc
48+
```
49+
50+
For this query, a vector index over the `vector` attribute and with the `cosine`
51+
metric is required. The `@q` bind variable needs to be a vector (array of numbers)
52+
with the dimension as specified in the vector index. It defines the point at
53+
which to look for similar documents (up to `5` in this case). How many documents can
54+
be found depends on the data as well as the search effort (see the `nProbe` option).
55+
56+
{{< info >}}
57+
- If there is more than one suitable vector index over the same attribute, it is
58+
undefined which one is selected.
59+
- You cannot have any `FILTER` operation between `FOR` and `LIMIT` for
60+
pre-filtering.
61+
{{< /info >}}
62+
63+
### APPROX_NEAR_COSINE()
64+
65+
`APPROX_NEAR_COSINE(vector1, vector2, options) → similarity`
66+
67+
Retrieve the approximate angular similarity using the cosine metric, accelerated
68+
by a matching vector index.
69+
70+
The higher the cosine similarity value is, the more similar the two vectors
71+
are. The closer it is to 0, the more different they are. The value can also
72+
be negative, indicating that the vectors are not similar and point in opposite
73+
directions. You need to sort in descending order so that the most similar
74+
documents come first, which is what a vector index using the `cosine` metric
75+
can provide.
76+
77+
- **vector1** (array of numbers): The first vector. Either this parameter or
78+
`vector2` needs to reference a stored attribute holding the vector embedding.
79+
- **vector2** (array of numbers): The second vector. Either this parameter or
80+
`vector1` needs to reference a stored attribute holding the vector embedding.
81+
- **options** (object, _optional_):
82+
- **nProbe** (number, _optional_): How many neighboring centroids respectively
83+
closest Voronoi cells to consider for the search results. The larger the number,
84+
the slower the search but the better the search results. If not specified, the
85+
`defaultNProbe` value of the vector index is used.
86+
- returns **similarity** (number): The approximate angular similarity between
87+
both vectors.
88+
89+
**Examples**
90+
91+
Return up to `10` similar documents based on their closeness to the vector
92+
`@q` according to the cosine metric:
93+
94+
```aql
95+
FOR doc IN coll
96+
SORT APPROX_NEAR_COSINE(doc.vector, @q) DESC
97+
LIMIT 10
98+
RETURN doc
99+
```
100+
101+
Return up to `5` similar documents as well as the similarity value,
102+
considering `20` neighboring centroids respectively closest Voronoi cells:
103+
104+
```aql
105+
FOR doc IN coll
106+
LET similarity = APPROX_NEAR_COSINE(doc.vector, @q, { nProbe: 20 })
107+
SORT similarity DESC
108+
LIMIT 5
109+
RETURN MERGE( { similarity }, doc)
110+
```
111+
112+
Return the similarity value and the document keys of up to `3` similar documents
113+
for multiple input vectors using a subquery. In this example, the input vectors
114+
are taken from ten random documents of the same collection:
115+
116+
```aql
117+
FOR docOuter IN coll
118+
LIMIT 10
119+
LET neighbors = (
120+
FOR docInner IN coll
121+
LET similarity = APPROX_NEAR_COSINE(docInner.vector, docOuter.vector)
122+
SORT similarity DESC
123+
LIMIT 3
124+
RETURN { key: docInner._key, similarity }
125+
)
126+
RETURN { key: docOuter._key, neighbors }
127+
```
128+
129+
### APPROX_NEAR_L2()
130+
131+
`APPROX_NEAR_L2(vector1, vector2, options) → similarity`
132+
133+
Retrieve the approximate distance using the L2 (Euclidean) metric, accelerated
134+
by a matching vector index.
135+
136+
The closer the distance is to 0, the more similar the two vectors are. The higher
137+
the value, the more different the they are. You need to sort in ascending order
138+
so that the most similar documents come first, which is what a vector index using
139+
the `l2` metric can provide.
140+
141+
- **vector1** (array of numbers): The first vector. Either this parameter or
142+
`vector2` needs to reference a stored attribute holding the vector embedding.
143+
- **vector2** (array of numbers): The second vector. Either this parameter or
144+
`vector1` needs to reference a stored attribute holding the vector embedding.
145+
- **options** (object, _optional_):
146+
- **nProbe** (number, _optional_): How many neighboring centroids to consider
147+
for the search results. The larger the number, the slower the search but the
148+
better the search results. If not specified, the `defaultNProbe` value of
149+
the vector index is used.
150+
- returns **similarity** (number): The approximate L2 (Euclidean) distance between
151+
both vectors.
152+
153+
**Examples**
154+
155+
Return up to `10` similar documents based on their closeness to the vector
156+
`@q` according to the L2 (Euclidean) metric:
157+
158+
```aql
159+
FOR doc IN coll
160+
SORT APPROX_NEAR_L2(doc.vector, @q)
161+
LIMIT 10
162+
RETURN doc
163+
```
164+
165+
Return up to `5` similar documents as well as the similarity value,
166+
considering `20` neighboring centroids respectively closest Voronoi cells:
167+
168+
```aql
169+
FOR doc IN coll
170+
LET similarity = APPROX_NEAR_L2(doc.vector, @q, { nProbe: 20 })
171+
SORT similarity
172+
LIMIT 5
173+
RETURN MERGE( { similarity }, doc)
174+
```
175+
176+
Return the similarity value and the document keys of up to `3` similar documents
177+
for multiple input vectors using a subquery. In this example, the input vectors
178+
are taken from ten random documents of the same collection:
179+
180+
```aql
181+
FOR docOuter IN coll
182+
LIMIT 10
183+
LET neighbors = (
184+
FOR docInner IN coll
185+
LET similarity = APPROX_NEAR_L2(docInner.vector, docOuter.vector)
186+
SORT similarity
187+
LIMIT 3
188+
RETURN { key: docInner._key, similarity }
189+
)
190+
RETURN { key: docOuter._key, neighbors }
191+
```

site/content/3.12/develop/http-api/indexes/_index.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,9 +247,9 @@ paths:
247247
`cacheEnabled` defaults to `false` and should only be used for indexes that
248248
are known to benefit from an extra layer of caching.
249249
250-
The optional attribute **inBackground** can be set to `true` to create the index
251-
in the background, which will not write-lock the underlying collection for
252-
as long as if the index is built in the foreground.
250+
The optional attribute **inBackground** can be set to `true` to keep the
251+
collection/shards available for write operations by not using an exclusive
252+
write lock for the duration of the index creation.
253253
parameters:
254254
- name: database-name
255255
in: path

site/content/3.12/develop/http-api/indexes/fulltext.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ paths:
4949
description: |
5050
Must be equal to `"fulltext"`.
5151
type: string
52+
example: fulltext
5253
name:
5354
description: |
5455
An easy-to-remember name for the index to look it up or refer to it in index hints.
@@ -58,9 +59,10 @@ paths:
5859
type: string
5960
fields:
6061
description: |
61-
an array of attribute names. Currently, the array is limited
62-
to exactly one attribute.
62+
A list with exactly one attribute path.
6363
type: array
64+
minItems: 1
65+
maxItems: 1
6466
items:
6567
type: string
6668
minLength:
@@ -71,22 +73,21 @@ paths:
7173
type: integer
7274
inBackground:
7375
description: |
74-
You can set this option to `true` to create the index
75-
in the background, which will not write-lock the underlying collection for
76-
as long as if the index is built in the foreground. The default value is `false`.
76+
Set this option to `true` to keep the collection/shards available for
77+
write operations by not using an exclusive write lock for the duration
78+
of the index creation.
7779
type: boolean
80+
default: false
7881
responses:
7982
'200':
8083
description: |
81-
If the index already exists, then a *HTTP 200* is
82-
returned.
84+
The index exists already.
8385
'201':
8486
description: |
85-
If the index does not already exist and could be created, then a *HTTP 201*
86-
is returned.
87+
The index is created as there is no such existing index.
8788
'404':
8889
description: |
89-
If the `collection-name` is unknown, then a *HTTP 404* is returned.
90+
The collection is unknown.
9091
tags:
9192
- Indexes
9293
```

site/content/3.12/develop/http-api/indexes/geo-spatial.md

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ paths:
1313
operationId: createIndexGeo
1414
description: |
1515
Creates a geo-spatial index in the collection `collection`, if
16-
it does not already exist. Expects an object containing the index details.
16+
it does not already exist.
1717
1818
Geo indexes are always sparse, meaning that documents that do not contain
1919
the index attributes or have non-numeric values in the index attributes
@@ -47,6 +47,7 @@ paths:
4747
description: |
4848
Must be equal to `"geo"`.
4949
type: string
50+
example: geo
5051
name:
5152
description: |
5253
An easy-to-remember name for the index to look it up or refer to it in index hints.
@@ -72,6 +73,8 @@ paths:
7273
All documents which do not have the attribute paths or which have
7374
values that are not suitable are ignored.
7475
type: array
76+
minItems: 1
77+
maxItems: 2
7578
items:
7679
type: string
7780
geoJson:
@@ -98,21 +101,21 @@ paths:
98101
type: boolean
99102
inBackground:
100103
description: |
101-
You can set this option to `true` to create the index
102-
in the background, which will not write-lock the underlying collection for
103-
as long as if the index is built in the foreground. The default value is `false`.
104+
Set this option to `true` to keep the collection/shards available for
105+
write operations by not using an exclusive write lock for the duration
106+
of the index creation.
104107
type: boolean
108+
default: false
105109
responses:
106110
'200':
107111
description: |
108-
If the index already exists, then a *HTTP 200* is returned.
112+
The index exists already.
109113
'201':
110114
description: |
111-
If the index does not already exist and could be created, then a *HTTP 201*
112-
is returned.
115+
The index is created as there is no such existing index.
113116
'404':
114117
description: |
115-
If the `collection` is unknown, then a *HTTP 404* is returned.
118+
The collection is unknown.
116119
tags:
117120
- Indexes
118121
```

site/content/3.12/develop/http-api/indexes/inverted.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ paths:
4444
description: |
4545
Must be equal to `"inverted"`.
4646
type: string
47+
example: inverted
4748
name:
4849
description: |
4950
An easy-to-remember name for the index to look it up or refer to it in index hints.
@@ -57,6 +58,7 @@ paths:
5758
default options, or objects to specify options for the fields (with the
5859
attribute path in the `name` property), or a mix of both.
5960
type: array
61+
minItems: 1
6062
items:
6163
type: object
6264
required:
@@ -473,10 +475,11 @@ paths:
473475
type: integer
474476
inBackground:
475477
description: |
476-
This attribute can be set to `true` to create the index
477-
in the background, not write-locking the underlying collection for
478-
as long as if the index is built in the foreground. The default value is `false`.
478+
Set this option to `true` to keep the collection/shards available for
479+
write operations by not using an exclusive write lock for the duration
480+
of the index creation.
479481
type: boolean
482+
default: false
480483
cleanupIntervalStep:
481484
description: |
482485
Wait at least this many commits between removing unused files in the
@@ -611,14 +614,13 @@ paths:
611614
responses:
612615
'200':
613616
description: |
614-
If the index already exists, then a *HTTP 200* is returned.
617+
The index exists already.
615618
'201':
616619
description: |
617-
If the index does not already exist and can be created, then a *HTTP 201*
618-
is returned.
620+
The index is created as there is no such existing index.
619621
'404':
620622
description: |
621-
If the `collection-name` is unknown, then a *HTTP 404* is returned.
623+
The collection is unknown.
622624
tags:
623625
- Indexes
624626
```

0 commit comments

Comments
 (0)