Skip to content

Commit b312a43

Browse files
committed
add command reference
1 parent 5cd82ab commit b312a43

File tree

6 files changed

+164
-16
lines changed

6 files changed

+164
-16
lines changed

.github/workflows/rust.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@ jobs:
2323
# Artifact name
2424
name: build-release
2525
# Directory containing files to upload
26-
path: target/release
26+
path: target/release/libredis_hnsw.so

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ Cargo.lock
1313
/.vscode
1414

1515
*.rdb
16+
*.aof

Readme.md

+139-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# HNSW for Redis
22

3-
`redis_hnsw` is a Hierarchical Navigable Small World (HNSW) implementation for Redis.
3+
`redis_hnsw` is a Hierarchical Navigable Small World (HNSW) implementation for Redis. Based on the paper [Efficient and robust approximate nearest neighbor search using Hierarchical Navigable Small World graphs](https://arxiv.org/abs/1603.09320). Currently only supports Euclidean distance, Hamming distance forthcoming.
44

55
## Getting Started
66

@@ -16,3 +16,141 @@ Add nodes - `hnsw.node.add <index_name> <node_name> <...data>`
1616
Delete nodes - `hnsw.node.del <index_name> <node_name>`
1717

1818
Search KNN - `hnsw.search <index_name> <k> <..data>`
19+
20+
21+
## Command Reference
22+
23+
### HNSW.NEW
24+
#### Format
25+
```
26+
HNSW.NEW {index} [DATA_DIM] [M] [EF_CONSTRUCTION]
27+
```
28+
#### Description
29+
Creates an HNSW index
30+
#### Example
31+
```
32+
HNSW.NEW foo 128 5 200
33+
```
34+
#### Parameters
35+
* **index**: name of the new index.
36+
* **DATA_DIM**: dimensionality of the data.
37+
* **M**: algorithm parameter for the number of neighbors to select for each node.
38+
* **EF_CONSTRUCTION**: algorithm parameter for the size of the dynamic candidate list.
39+
#### Complexity
40+
O(1)
41+
#### Returns
42+
OK or an error
43+
44+
### HNSW.GET
45+
#### Format
46+
```
47+
HNSW.GET {index}
48+
```
49+
#### Description
50+
Retrieves an HNSW index
51+
#### Example
52+
```
53+
HNSW.GET foo
54+
```
55+
#### Parameters
56+
* **index**: name of the index.
57+
#### Complexity
58+
O(1)
59+
#### Returns
60+
**Array Reply** key-value pairs of index attributes
61+
62+
### HNSW.DEL
63+
#### Format
64+
```
65+
HNSW.DEL {index}
66+
```
67+
#### Description
68+
Deletes an HNSW index
69+
#### Example
70+
```
71+
HNSW.DEL foo
72+
```
73+
#### Parameters
74+
* **index**: name of the index.
75+
#### Complexity
76+
O(1)
77+
#### Returns
78+
OK or an error
79+
80+
### HNSW.NODE.ADD
81+
#### Format
82+
```
83+
HNSW.NODE.ADD {index} {node} {...DATA}
84+
```
85+
#### Description
86+
Adds an element to the index
87+
#### Example
88+
```
89+
HNSW.NODE.ADD foo bar 1.0 1.0 1.0 1.0
90+
```
91+
#### Parameters
92+
* **index**: name of the index
93+
* **node**: name of the new node
94+
* **DATA**: space separated vector of data. Total entries must match `DATA_DIM` of index
95+
#### Complexity
96+
O(log(n)) where n is the number of nodes in the index
97+
#### Returns
98+
OK or an error
99+
100+
### HNSW.NODE.GET
101+
#### Format
102+
```
103+
HNSW.NODE.GET {index} {node}
104+
```
105+
#### Description
106+
Retrieves an element from the index
107+
#### Example
108+
```
109+
HNSW.NODE.GET foo bar
110+
```
111+
#### Parameters
112+
* **index**: name of the index
113+
* **node**: name of the node
114+
#### Complexity
115+
O(1)
116+
#### Returns
117+
**Array Reply** key-value pairs of node attributes
118+
119+
### HNSW.NODE.DEL
120+
#### Format
121+
```
122+
HNSW.NODE.DEL {index} {node}
123+
```
124+
#### Description
125+
Removes an element from the index
126+
#### Example
127+
```
128+
HNSW.NODE.DEL foo bar
129+
```
130+
#### Parameters
131+
* **index**: name of the index
132+
* **node**: name of the node
133+
#### Complexity
134+
O(log(n)) where n is the number of nodes in the index
135+
#### Returns
136+
OK or an error
137+
138+
### HNSW.SEARCH
139+
#### Format
140+
```
141+
HNSW.SEARCH {index} {K} {...DATA}
142+
```
143+
#### Description
144+
Search the index for the K nearest elements to the query
145+
#### Example
146+
```
147+
HNSW.SEARCH foo 5 0.0 0.0 0.0 0.0
148+
```
149+
#### Parameters
150+
* **index**: name of the index
151+
* **K**: number of nearest neighbors to return
152+
* **DATA**: space separated vector of query data. Total entries must match `DATA_DIM` of index
153+
#### Complexity
154+
O(log(n)) where n is the number of nodes in the index
155+
#### Returns
156+
**Array Reply** where the first element is the number of results, followed by key-value pairs of similiarity and returned node key.

cmd.sh

+17-12
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
1-
# redis-cli hnsw.new test1 128 5
1+
redis-cli hnsw.new test1 128 5
22

3-
# for i in {1..100}
4-
# do
5-
# data=$(printf "${i} %.0s" {1..128})
6-
# redis-cli hnsw.node.add test1 node${i-1} ${data}
7-
# done
3+
for i in {1..100}
4+
do
5+
data=$(printf "${i} %.0s" {1..128})
6+
redis-cli hnsw.node.add test1 node${i-1} ${data}
7+
done
88

9-
data=$(printf "50 %.0s" {1..128})
9+
redis-cli bgsave
10+
11+
redis-cli hnsw.get test1
12+
redis-cli hnsw.node.get test1 node1
13+
14+
data=$(printf "2 %.0s" {1..128})
1015
redis-cli hnsw.search test1 5 ${data}
1116

12-
# for i in {1..100}
13-
# do
14-
# redis-cli hnsw.node.del test1 node${i-1}
15-
# done
17+
for i in {1..100}
18+
do
19+
redis-cli hnsw.node.del test1 node${i-1}
20+
done
1621

17-
# redis-cli hnsw.del test1
22+
redis-cli hnsw.del test1

src/hnsw/hnsw.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -864,7 +864,11 @@ impl Index {
864864
let c = w.pop().unwrap();
865865
let cr = c.read();
866866
let cnr = cr.node.read();
867-
res.push(SearchResult::new(cr.sim, &cnr.name, &cnr.data));
867+
res.push(SearchResult::new(
868+
cr.sim,
869+
(&cnr.name).split(".").collect::<Vec<&str>>()[2],
870+
&cnr.data,
871+
));
868872
}
869873
res
870874
}

src/types.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ impl SearchResultRedis {
417417
pub fn as_redisvalue(&self) -> RedisValue {
418418
let mut reply: Vec<RedisValue> = Vec::new();
419419

420-
reply.push("sim".into());
420+
reply.push("similarity".into());
421421
reply.push(self.sim.into());
422422

423423
reply.push("name".into());

0 commit comments

Comments
 (0)