Skip to content

Commit da4b8bf

Browse files
nagrahamsejoker
andauthored
Vectorize: Add Content to the Best Practices Documentation (#21913)
* Vectorize: Update Best Practices with a section on improving write Throughput * Vectorize: Update Range Query docs to draw attention to prefix searching * Vectorize: Add section on how to optimize Metadata Index values * Update src/content/docs/vectorize/reference/metadata-filtering.mdx --------- Co-authored-by: Yevgen Safronov <[email protected]>
1 parent a89b6f2 commit da4b8bf

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

src/content/docs/vectorize/best-practices/insert-vectors.mdx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,20 @@ For example, a vector embedding representing an image could include the path to
4747
{ id: '1', values: [32.4, 74.1, 3.2, ...], metadata: { path: 'r2://bucket-name/path/to/image.png', format: 'png', category: 'profile_image' } }
4848
```
4949

50+
### Performance Tips When Filtering by Metadata
51+
52+
When creating metadata indexes for a large Vectorize index, we encourage users to think ahead and plan how they will query for vectors with filters on this metadata.
53+
54+
Carefully consider the cardinality of metadata values in relation to your queries. Cardinality is the level of uniqueness of data values within a set. Low cardinality means there are only a few unique values: for instance, the number of planets in the Solar System; the number of countries in the world. High cardinality means there are many unique values: UUIv4 strings; timestamps with millisecond precision.
55+
56+
High cardinality is good for the selectiveness of the equal (`$eq`) filter. For example, if you want to find vectors associated with one user's id. But the filter is not going to help if all vectors have the same value. That's an example of extreme low cardinality.
57+
58+
High cardinality can also impact range queries, which searches across multiple unqiue metadata values. For example, an indexed metadata value using millisecond timestamps will see lower performance if the range spans long periods of time in which thousands of vectors with unique timestamps were written.
59+
60+
Behind the scenes, Vectorize uses a reverse index to map values to vector ids. If the number of unique values in a particular range is too high, then that requires reading large portions of the index (a full index scan in the worst case). This would lead to memory issues, so Vectorize will degrade performance and the accuracy of the query in order to finish the request.
61+
62+
One approach for high cardinality data is to somehow create buckets where more vectors get grouped to the same value. Continuing the millisecond timestamp example, let's imagine we typically filter with date ranges that have 5 minute increments of granularity. We could use a timestamp which is rounded down to the last 5 minute point. This "windows" our metadata values into 5 minute increments. And we can still store the original millisecond timestamp as a separate non-indexed field.
63+
5064
## Namespaces
5165

5266
Namespaces provide a way to segment the vectors within your index. For example, by customer, merchant or store ID.
@@ -94,6 +108,16 @@ let matches = await env.TUTORIAL_INDEX.query(queryVector, {
94108
});
95109
```
96110

111+
## Improve Write Throughput
112+
113+
One way to reduce the time to make updates visible in queries is to batch more vectors into fewer requests. This is important for write-heavy workloads. To see how many vectors you can write in a single request, please refer to the [Limits](/vectorize/platform/limits/) page.
114+
115+
Vectorize writes changes immeditely to a write ahead log for durability. To make these writes visible for reads, an asynchronous job needs to read the current index files from R2, create an updated index, write the new index files back to R2, and commit the change. To keep the overhead of writes low and improve write throughput, Vectorize will combine multiple changes together into a single batch. It sets the maximum size of a batch to 200,000 total vectors or to 1,000 individual updates, whichever limit it hits first.
116+
117+
For example, let's say we have 250,000 vectors we would like to insert into our index. We decide to insert them one at a time, calling the insert API 250,000 times. Vectorize will only process 1000 vectors in each job, and will need to work through 250 total jobs. This could take at least an hour to do.
118+
119+
The better approach is to batch our updates. For example, we can split our 250,000 vectors into 100 files, where each file has 2,500 vectors. We would call the insert HTTP API 100 times. Vectorize would update the index in only 2 or 3 jobs. All 250,000 vectors will visible in queries within minutes.
120+
97121
## Examples
98122

99123
### Workers API

src/content/docs/vectorize/reference/metadata-filtering.mdx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ An optional `filter` property on `query()` method specifies metadata filters:
4949
- For `$eq` and `$ne`, `filter` object non-nested values can be `string`, `number`, `boolean`, or `null` values.
5050
- For `$in` and `$nin`, `filter` object values can be arrays of `string`, `number`, `boolean`, or `null` values.
5151
- Upper-bound range queries (i.e. `$lt` and `$lte`) can be combined with lower-bound range queries (i.e. `$gt` and `$gte`) within the same filter. Other combinations are not allowed.
52-
- For range queries (i.e. `$lt`, `$lte`, `$gt`, `$gte`), `filter` object non-nested values can be `string` or `number` values. Strings are ordered lexicographically.
53-
- Range queries involving a large number of vectors (~10M and above) may experience reduced accuracy.
52+
- For range queries (i.e. `$lt`, `$lte`, `$gt`, `$gte`), `filter` object non-nested values can be `string` or `number` values. Strings are ordered lexicographically.
53+
- Range queries involving a large number of vectors (~10M and above) may experience reduced accuracy.
5454

5555
### Namespace versus metadata filtering
5656

@@ -92,7 +92,9 @@ Both [namespaces](/vectorize/best-practices/insert-vectors/#namespaces) and meta
9292
```
9393

9494
#### Range query involving strings
95-
Range queries can be used to implement prefix searching on string metadata fields.
95+
96+
Range queries can implement **prefix searching** on string metadata fields. This is also like a **starts_with** filter.
97+
9698
For example, the following filter matches all values starting with "net":
9799

98100
```json

0 commit comments

Comments
 (0)