Set Up Schema and HNSW Index for Multi-Vector Search
Prepare the data model by storing each vector embedding with the business identifiers used to group multi-vector results and any scalar attributes used to filter them. Then create an HNSW vector index that includes the columns required by the multi-vector query.
Define the Table Schema
Create a table to store your vector-embedded data along with the attributes that you will use for partitioning (for example, book_id and paragraph_id) and query filtering (for example, create_date). In this example, each book contains multiple paragraphs, and each row stores an individually embedded sentence vector:
CREATE TABLE hnsw_mvs_books (
record_id NUMBER PRIMARY KEY,
book_id NUMBER NOT NULL,
paragraph_id NUMBER NOT NULL,
sentence VECTOR(2, FLOAT32),
create_date DATE NOT NULL
);
Every column used in a PARTITIONS BY clause must be a base-table column and must be stored as an included column in the HNSW index. This example also includes create_date so that it is available to the HNSW filtering paths:
Create the HNSW Index
Create the HNSW index on the vector column and use included columns to support the grouping and filtering requirements of the multi-vector query.
For HNSW multi-vector search, include columns that the query commonly uses to:
- define result groups in
PARTITIONS BYclauses; - filter the eligible rows; or
- project non-vector attributes directly from the index.
Every column referenced by a PARTITIONS BY clause must be included in the HNSW index. In the following example, book_id and paragraph_id are required grouping columns. create_date is also included so that it is available to the HNSW filtering paths:
CREATE VECTOR INDEX hnsw_mvs_books_ix
ON hnsw_mvs_books (sentence)
INCLUDE (book_id, paragraph_id, create_date)
ORGANIZATION INMEMORY NEIGHBOR GRAPH
WITH TARGET ACCURACY 95
DISTANCE EUCLIDEAN
PARAMETERS (TYPE HNSW, NEIGHBORS 5, EFCONSTRUCTION 10);
This definition creates an HNSW index on the sentence vector, requests a target accuracy of 95, and uses Euclidean distance. NEIGHBORS controls the maximum number of graph connections per vector, and EFCONSTRUCTION controls how many candidate neighbors are considered while the index is built.
The distance metric specified in the search query must match the index distance metric. A projected column such as record_id does not have to be included unless the application needs to retrieve it directly from the index; Oracle AI Database can retrieve nonincluded projected columns from the base table by row ID.
After completing the schema and index setup, run a multi-vector query whose PARTITIONS BY columns match the grouping columns included in the index. The optimizer can then consider the HNSW partitioned-scan access path.
Example: Run an HNSW Multi-Vector Search
The following query uses [0.0, 0.0] as the query vector. It requests at most two books, three paragraphs within each selected book, and four sentences within each selected paragraph:
SELECT book_id, paragraph_id
FROM hnsw_mvs_books
ORDER BY VECTOR_DISTANCE(
sentence,
TO_VECTOR('[0.0, 0.0]', 2, FLOAT32),
EUCLIDEAN
)
FETCH APPROXIMATE FIRST 2 PARTITIONS BY book_id,
3 PARTITIONS BY paragraph_id,
4 ROWS ONLY;
This following output illustrates two selected books (101 and 202), with three paragraph groups (1, 2, and 3) in each book. Each paragraph contributes four sentence rows.
The rows are ordered by VECTOR_DISTANCE, as specified in the query. The PARTITIONS BY clauses determine which book and paragraph partitions contribute rows and set the limits for each; book_id or paragraph_id:
BOOK_ID PARAGRAPH_ID
------------ ------------
101 1
101 1
101 1
101 1
202 1
202 1
202 1
202 1
101 2
101 2
101 2
101 2
202 2
202 2
202 2
202 2
101 3
101 3
101 3
101 3
202 3
202 3
202 3
202 3
24 rows selected.
HNSW search is approximate, the query can return fewer rows than theoretical maximum even when the base table contains enough rows to fill every group. The partitioned row limit creates a hierarchy of result groups. In the example above, the query requests:
- up to 2 book groups;
- within each selected book, up to 3 paragraph groups;
- within each selected paragraph, up to 4 sentence rows.
If every requested group is filled, the query can therefore return at most 2 * 3 * 4 = 24 rows. During an approximate HNSW search, sentence candidates are ranked by vector distance and used to populate paragraph groups. The best-ranked paragraph groups then contribute to their parent book groups. The search returns the selected book groups along with their best-matching paragraphs and sentence rows
Example: In-Filter Multi-Vector Query
SELECT book_id, paragraph_id
FROM hnsw_mvs_books
WHERE EXTRACT(YEAR FROM create_date) = 2020
ORDER BY VECTOR_DISTANCE(
sentence,
TO_VECTOR('[0.0, 0.0]', 2, FLOAT32),
EUCLIDEAN
)
FETCH APPROXIMATE FIRST 2 PARTITIONS BY book_id,
3 PARTITIONS BY paragraph_id,
4 ROWS ONLY;
This query restricts eligible rows to those rows with a create_date in 2020. The query then applies the same multi-vector limits: up to two books, three paragraphs per selected book, and four sentences per selected paragraph. Including create_date makes it available to the HNSW index filtering path. Predicates on nonincluded base-table columns can also be evaluated by accessing candidate rows from the base table, which may add table lookups.
See Also: