Vector Search HNSW Indexing Encoding #2316
Replies: 4 comments 10 replies
-
Hiii @PragmaTwice @git-hulk , as discussed in here last time, this is the encoding plan to implement basic vector search in kvrocks. Welcome any questions/concerns/feedback!! I couldn't think of a better way for |
Beta Was this translation helpful? Give feedback.
-
From my experience, the space amplify of vector index would be huge and might not so sutable for kv-case, we can rush a fast poc and try comparing the space for storing in kv or storing in a self-defined blob format |
Beta Was this translation helpful? Give feedback.
-
Thank you for your great design proposal and your efforts! I think there are generally no major issues with your proposal, but there are a few points to note:
|
Beta Was this translation helpful? Give feedback.
-
How did you search? Is it through querying the underlying rocksdb to obtain the various points on the hnsw graph? |
Beta Was this translation helpful? Give feedback.
-
Vector Search HNSW Indexing Encoding
Goal
We aim to integrate the Hierarchical Navigable Small World (HNSW) algorithm into Kvrocks to provide an efficient, scalable solution for approximate nearest neighbour searches in high-dimensional spaces.
Background
HNSW builds a multi-layered structure where each layer acts as a separate graph. The top layers contain fewer nodes and are used to facilitate fast traversal over large distances within the dataset. Lower layers have more nodes, enabling precise navigation and search in the neighborhood of the query point. In a word, HNSW is a skiplist of graph.
The bottom-most level 0 NSW layer contains all information, and we randomly put some vectors to the upper layer (more upper layer has fewer elements), which are also NSW indexes. The search process starts from the upper-most layer, and uses neighbors in that layer as the entry points of the lower layer.
Reference: Write a vector Database
HNSW metadata
index_name
flags
(1 byte)expiration
(Ebytes)version
(8 bytes)size
(Sbytes)storing_data_type
(1 byte): Vectors could be stored in both JSON and hashes. (0 = hashes, 1 = JSON).vector_field
(Sbyte)entryPoint
(Sbytes): Entry node ID for search initiation, i.e. key for returned data??.type
(1 byte): Enum property to indicate vector type (0 = FLOAT32, 1 = FLOAT64).dim
(2 bytes): Stores the vector dimension as a 16-bit integer.distanceMetric
(1 byte): Enum for distance metric (0 = L2, 1 = IP, 2 = COSINE).initialCap
(4 bytes): Initial capacity as a 32-bit integer.M
(2 bytes): Maximum number of outgoing edges per node as a 16-bit integer.efConstruction
(4 bytes): Size of the dynamic candidate list during construction as a 32-bit integer.efRuntime
(4 bytes): Size of the candidate list during search as a 32-bit integer.epsilon
(4 bytes): Floating point to extend search radius, stored as a 32-bit float.maxElements
(4 bytes): Maximum elements stored as a 32-bit integer.currentLevel
(2 bytes): Highest level nodes currently reach as a 16-bit integer.HNSW Graph sub key-values
Nodes
index_name | level | node_id
level
is the current level of the nodenode_id
is the key for the indexed data pointnum_neighbours
Edges
index_name | level | node_id | connected_node_id
computed_distance
Inverted Index Key-values
After you create an index, Redis Stack automatically indexes any existing, modified, or newly created JSON documents stored in the database. When inserting a new entry, it should be aware that it’s part of the HNSW indexing.
type | prefix | vector_field
index_name
APIs
All interfaces and internal APIs will be implemented based on:
Appendix
Beta Was this translation helpful? Give feedback.
All reactions