Skip to content

Commit 0e7dde0

Browse files
author
Sam Partee
authored
rvl stats (#46)
This PR introduces the new ``rvl stats`` command.
1 parent d5c1b50 commit 0e7dde0

File tree

8 files changed

+340
-45
lines changed

8 files changed

+340
-45
lines changed

docs/user_guide/getting_started_01.ipynb

Lines changed: 95 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,8 @@
211211
"name": "stdout",
212212
"output_type": "stream",
213213
"text": [
214-
"\u001b[32m14:56:24\u001b[0m \u001b[34m[RedisVL]\u001b[0m \u001b[1;30mINFO\u001b[0m Indices:\n",
215-
"\u001b[32m14:56:24\u001b[0m \u001b[34m[RedisVL]\u001b[0m \u001b[1;30mINFO\u001b[0m 1. user_index\n"
214+
"\u001b[32m15:14:34\u001b[0m \u001b[34m[RedisVL]\u001b[0m \u001b[1;30mINFO\u001b[0m Indices:\n",
215+
"\u001b[32m15:14:34\u001b[0m \u001b[34m[RedisVL]\u001b[0m \u001b[1;30mINFO\u001b[0m 1. user_index\n"
216216
]
217217
}
218218
],
@@ -221,6 +221,40 @@
221221
"!rvl index listall"
222222
]
223223
},
224+
{
225+
"cell_type": "code",
226+
"execution_count": 6,
227+
"metadata": {},
228+
"outputs": [
229+
{
230+
"name": "stdout",
231+
"output_type": "stream",
232+
"text": [
233+
"\n",
234+
"\n",
235+
"Index Information:\n",
236+
"╭──────────────┬────────────────┬────────────┬─────────────────┬────────────╮\n",
237+
"│ Index Name │ Storage Type │ Prefixes │ Index Options │ Indexing │\n",
238+
"├──────────────┼────────────────┼────────────┼─────────────────┼────────────┤\n",
239+
"│ user_index │ HASH │ ['v1'] │ [] │ 0 │\n",
240+
"╰──────────────┴────────────────┴────────────┴─────────────────┴────────────╯\n",
241+
"Index Fields:\n",
242+
"╭────────────────┬────────────────┬─────────┬────────────────┬────────────────╮\n",
243+
"│ Name │ Attribute │ Type │ Field Option │ Option Value │\n",
244+
"├────────────────┼────────────────┼─────────┼────────────────┼────────────────┤\n",
245+
"│ credit_score │ credit_score │ TAG │ SEPARATOR │ , │\n",
246+
"│ job │ job │ TEXT │ WEIGHT │ 1 │\n",
247+
"│ age │ age │ NUMERIC │ │ │\n",
248+
"│ user_embedding │ user_embedding │ VECTOR │ │ │\n",
249+
"╰────────────────┴────────────────┴─────────┴────────────────┴────────────────╯\n"
250+
]
251+
}
252+
],
253+
"source": [
254+
"# use the CLI to print fields in the index\n",
255+
"!rvl index info -i user_index"
256+
]
257+
},
224258
{
225259
"cell_type": "markdown",
226260
"metadata": {},
@@ -232,7 +266,7 @@
232266
},
233267
{
234268
"cell_type": "code",
235-
"execution_count": 6,
269+
"execution_count": 7,
236270
"metadata": {},
237271
"outputs": [],
238272
"source": [
@@ -252,13 +286,13 @@
252286
},
253287
{
254288
"cell_type": "code",
255-
"execution_count": 7,
289+
"execution_count": 8,
256290
"metadata": {},
257291
"outputs": [
258292
{
259293
"data": {
260294
"text/html": [
261-
"<table><tr><th>id</th><th>vector_distance</th><th>user</th><th>age</th><th>job</th><th>credit_score</th></tr><tr><td>v1:7f2670effaa140adacc13a4a74eac358</td><td>0</td><td>john</td><td>1</td><td>engineer</td><td>high</td></tr><tr><td>v1:7f01fd2181f44eb181caf6262b1a2a6e</td><td>0</td><td>mary</td><td>2</td><td>doctor</td><td>low</td></tr><tr><td>v1:6a6fee8801cd48ecadad722cca4962bf</td><td>0.653301358223</td><td>joe</td><td>3</td><td>dentist</td><td>medium</td></tr></table>"
295+
"<table><tr><th>id</th><th>vector_distance</th><th>user</th><th>age</th><th>job</th><th>credit_score</th></tr><tr><td>v1:1d91681e86f64175ac2a85d5c0d82c04</td><td>0</td><td>john</td><td>1</td><td>engineer</td><td>high</td></tr><tr><td>v1:336fba2e3e8846d0be5689a8f21da149</td><td>0</td><td>mary</td><td>2</td><td>doctor</td><td>low</td></tr><tr><td>v1:3a059b1b202c416f9a661ed1b60e7d61</td><td>0.653301358223</td><td>joe</td><td>3</td><td>dentist</td><td>medium</td></tr></table>"
262296
],
263297
"text/plain": [
264298
"<IPython.core.display.HTML object>"
@@ -297,13 +331,13 @@
297331
},
298332
{
299333
"cell_type": "code",
300-
"execution_count": 8,
334+
"execution_count": 9,
301335
"metadata": {},
302336
"outputs": [
303337
{
304338
"data": {
305339
"text/html": [
306-
"<table><tr><th>id</th><th>vector_distance</th><th>user</th><th>age</th><th>job</th><th>credit_score</th></tr><tr><td>v1:7f2670effaa140adacc13a4a74eac358</td><td>0</td><td>john</td><td>1</td><td>engineer</td><td>high</td></tr><tr><td>v1:7f01fd2181f44eb181caf6262b1a2a6e</td><td>0</td><td>mary</td><td>2</td><td>doctor</td><td>low</td></tr><tr><td>v1:6a6fee8801cd48ecadad722cca4962bf</td><td>0.653301358223</td><td>joe</td><td>3</td><td>dentist</td><td>medium</td></tr></table>"
340+
"<table><tr><th>id</th><th>vector_distance</th><th>user</th><th>age</th><th>job</th><th>credit_score</th></tr><tr><td>v1:1d91681e86f64175ac2a85d5c0d82c04</td><td>0</td><td>john</td><td>1</td><td>engineer</td><td>high</td></tr><tr><td>v1:336fba2e3e8846d0be5689a8f21da149</td><td>0</td><td>mary</td><td>2</td><td>doctor</td><td>low</td></tr><tr><td>v1:3a059b1b202c416f9a661ed1b60e7d61</td><td>0.653301358223</td><td>joe</td><td>3</td><td>dentist</td><td>medium</td></tr></table>"
307341
],
308342
"text/plain": [
309343
"<IPython.core.display.HTML object>"
@@ -333,13 +367,13 @@
333367
},
334368
{
335369
"cell_type": "code",
336-
"execution_count": 9,
370+
"execution_count": 10,
337371
"metadata": {},
338372
"outputs": [
339373
{
340374
"data": {
341375
"text/html": [
342-
"<table><tr><th>id</th><th>vector_distance</th><th>user</th><th>age</th><th>job</th><th>credit_score</th></tr><tr><td>v1:ecac61a5802448f695d775d50e925826</td><td>0</td><td>john</td><td>1</td><td>engineer</td><td>high</td></tr><tr><td>v1:20198d650bb84295a9c718680a7506b1</td><td>0</td><td>mary</td><td>2</td><td>doctor</td><td>low</td></tr><tr><td>v1:a7e9aa9466834e00ab91f69aae7bc71e</td><td>0.653301358223</td><td>joe</td><td>3</td><td>dentist</td><td>medium</td></tr></table>"
376+
"<table><tr><th>id</th><th>vector_distance</th><th>user</th><th>age</th><th>job</th><th>credit_score</th></tr><tr><td>v1:a88e113051364b94bbefa29d6234725d</td><td>0</td><td>john</td><td>1</td><td>engineer</td><td>high</td></tr><tr><td>v1:f850fc9073b8420984acfc79e960fdb4</td><td>0</td><td>mary</td><td>2</td><td>doctor</td><td>low</td></tr><tr><td>v1:c0aecbe4ffe14c15b574563228ea000e</td><td>0.653301358223</td><td>joe</td><td>3</td><td>dentist</td><td>medium</td></tr></table>"
343377
],
344378
"text/plain": [
345379
"<IPython.core.display.HTML object>"
@@ -369,6 +403,58 @@
369403
"results = await index.query(query)\n",
370404
"result_print(results)"
371405
]
406+
},
407+
{
408+
"cell_type": "code",
409+
"execution_count": 11,
410+
"metadata": {},
411+
"outputs": [
412+
{
413+
"name": "stdout",
414+
"output_type": "stream",
415+
"text": [
416+
"\n",
417+
"Statistics:\n",
418+
"╭─────────────────────────────┬─────────────╮\n",
419+
"│ Stat Key │ Value │\n",
420+
"├─────────────────────────────┼─────────────┤\n",
421+
"│ num_docs │ 3 │\n",
422+
"│ num_terms │ 4 │\n",
423+
"│ max_doc_id │ 3 │\n",
424+
"│ num_records │ 13 │\n",
425+
"│ percent_indexed │ 1 │\n",
426+
"│ hash_indexing_failures │ 0 │\n",
427+
"│ number_of_uses │ 3 │\n",
428+
"│ bytes_per_record_avg │ 2.46154 │\n",
429+
"│ doc_table_size_mb │ 0.000294685 │\n",
430+
"│ inverted_sz_mb │ 3.05176e-05 │\n",
431+
"│ key_table_size_mb │ 0.000110626 │\n",
432+
"│ offset_bits_per_record_avg │ 8 │\n",
433+
"│ offset_vectors_sz_mb │ 3.8147e-06 │\n",
434+
"│ offsets_per_term_avg │ 0.307692 │\n",
435+
"│ records_per_doc_avg │ 4.33333 │\n",
436+
"│ sortable_values_size_mb │ 0 │\n",
437+
"│ total_indexing_time │ 0.1 │\n",
438+
"│ total_inverted_index_blocks │ 8 │\n",
439+
"│ vector_index_sz_mb │ 0.164604 │\n",
440+
"╰─────────────────────────────┴─────────────╯\n"
441+
]
442+
}
443+
],
444+
"source": [
445+
"# We can also use the CLI to check the stats for the index we just used\n",
446+
"!rvl stats -i user_index"
447+
]
448+
},
449+
{
450+
"cell_type": "code",
451+
"execution_count": 12,
452+
"metadata": {},
453+
"outputs": [],
454+
"source": [
455+
"# clean up the index\n",
456+
"await index.delete()"
457+
]
372458
}
373459
],
374460
"metadata": {

redisvl/cli/index.py

Lines changed: 70 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import argparse
22
import sys
3+
from tabulate import tabulate
34
from argparse import Namespace
4-
from pprint import pprint
5+
56

67
from redisvl.cli.log import get_logger
7-
from redisvl.cli.utils import create_redis_url
8+
from redisvl.cli.utils import create_redis_url, add_index_parsing_options
89
from redisvl.index import SearchIndex
910
from redisvl.utils.connection import get_redis_connection
10-
from redisvl.utils.utils import convert_bytes
11+
from redisvl.utils.utils import convert_bytes, make_dict
1112

1213
logger = get_logger("[RedisVL]")
1314

@@ -30,22 +31,14 @@ def __init__(self):
3031
parser = argparse.ArgumentParser(usage=self.usage)
3132

3233
parser.add_argument("command", help="Subcommand to run")
33-
34-
parser.add_argument(
35-
"-i", "--index", help="Index name", type=str, required=False
36-
)
3734
parser.add_argument(
38-
"-s", "--schema", help="Path to schema file", type=str, required=False
39-
)
40-
parser.add_argument("--host", help="Redis host", type=str, default="localhost")
41-
parser.add_argument("-p", "--port", help="Redis port", type=int, default=6379)
42-
parser.add_argument(
43-
"--user", help="Redis username", type=str, default="default"
44-
)
45-
parser.add_argument("--ssl", help="Use SSL", action="store_true")
46-
parser.add_argument(
47-
"-a", "--password", help="Redis password", type=str, default=""
35+
"-f",
36+
"--format",
37+
help="Output format for info command",
38+
type=str,
39+
default="rounded_outline"
4840
)
41+
parser = add_index_parsing_options(parser)
4942

5043
args = parser.parse_args(sys.argv[2:])
5144
if not hasattr(self, args.command):
@@ -78,8 +71,7 @@ def info(self, args: Namespace):
7871
rvl index info -i <index_name> | -s <schema_path>
7972
"""
8073
index = self._connect_to_index(args)
81-
logger.info("Index information:")
82-
pprint(index.info())
74+
_display_in_table(index.info(), output_format=args.format)
8375

8476
def listall(self, args: Namespace):
8577
"""List all indices
@@ -133,3 +125,62 @@ def _connect_to_index(self, args: Namespace) -> SearchIndex:
133125
exit(0)
134126

135127
return index
128+
129+
def _display_in_table(index_info, output_format="rounded_outline"):
130+
print("\n")
131+
attributes = index_info.get("attributes", [])
132+
definition = make_dict(index_info.get("index_definition"))
133+
index_info = [
134+
index_info.get("index_name"),
135+
definition.get("key_type"),
136+
definition.get("prefixes"),
137+
index_info.get("index_options"),
138+
index_info.get("indexing"),
139+
]
140+
141+
# Display the index information in tabular format
142+
print("Index Information:")
143+
print(
144+
tabulate(
145+
[index_info],
146+
headers=[
147+
"Index Name",
148+
"Storage Type",
149+
"Prefixes",
150+
"Index Options",
151+
"Indexing",
152+
],
153+
tablefmt=output_format,
154+
)
155+
)
156+
157+
attr_values = []
158+
headers = [
159+
"Name",
160+
"Attribute",
161+
"Type",
162+
]
163+
164+
for attrs in attributes:
165+
attr = make_dict(attrs)
166+
167+
values = [attr.get("identifier"), attr.get("attribute"), attr.get("type")]
168+
if len(attrs) > 5:
169+
options = make_dict(attrs)
170+
for k, v in options.items():
171+
if k not in ["identifier", "attribute", "type"]:
172+
headers.append("Field Option")
173+
headers.append("Option Value")
174+
values.append(k)
175+
values.append(v)
176+
attr_values.append(values)
177+
178+
# Display the attributes in tabular format
179+
print("Index Fields:")
180+
print(
181+
tabulate(
182+
attr_values,
183+
headers=headers,
184+
tablefmt=output_format,
185+
)
186+
)

redisvl/cli/main.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
from redisvl.cli.index import Index
55
from redisvl.cli.log import get_logger
66
from redisvl.cli.version import Version
7+
from redisvl.cli.stats import Stats
8+
79

810
logger = get_logger(__name__)
911

@@ -14,6 +16,7 @@ def _usage():
1416
"Commands:",
1517
"\tindex Index manipulation (create, delete, etc.)",
1618
"\tversion Obtain the version of RedisVL",
19+
"\tstats Obtain statistics about an index",
1720
]
1821
return "\n".join(usage) + "\n"
1922

@@ -43,3 +46,8 @@ def index(self):
4346
def version(self):
4447
Version()
4548
exit(0)
49+
50+
def stats(self):
51+
Stats()
52+
exit(0)
53+

0 commit comments

Comments
 (0)