From 7cc33bcf608828493cc1bf68762806e17ab37b77 Mon Sep 17 00:00:00 2001 From: Robert Shelton Date: Thu, 26 Sep 2024 07:44:56 -0700 Subject: [PATCH 1/5] float16 recipe --- .../vector-search/02_float16_support.ipynb | 637 ++++++++++++++++++ 1 file changed, 637 insertions(+) create mode 100644 python-recipes/vector-search/02_float16_support.ipynb diff --git a/python-recipes/vector-search/02_float16_support.ipynb b/python-recipes/vector-search/02_float16_support.ipynb new file mode 100644 index 0000000..bddd147 --- /dev/null +++ b/python-recipes/vector-search/02_float16_support.ipynb @@ -0,0 +1,637 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'5.0.8'" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import redis\n", + "redis.__version__" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![Redis](https://redis.io/wp-content/uploads/2024/04/Logotype.svg?auto=webp&quality=85,75&width=120)\n", + "# Using smaller vector types\n", + "\n", + "With the [Redis 7.4 release](https://redis.io/blog/announcing-redis-community-edition-and-redis-stack-74/) there is now support for bfloat16 and float16 data types in the vector store. Using this type is exactly the same as using float32 or other data types but will require a conversion if seeking to replace previously stored objects.\n", + "\n", + "This tutorial will walk through repopulating and index as such.\n", + "\n", + "## Packages" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "huggingface/tokenizers: The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...\n", + "To disable this warning, you can either:\n", + "\t- Avoid using `tokenizers` before the fork if possible\n", + "\t- Explicitly set the environment variable TOKENIZERS_PARALLELISM=(true | false)\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "^C\n", + "\u001b[31mERROR: Operation cancelled by user\u001b[0m\u001b[31m\n", + "\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m24.0\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.2\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n", + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "# NBVAL_SKIP\n", + "%pip install -q redis redisvl numpy sentence-transformers" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Install Redis Stack\n", + "\n", + "Later in this tutorial, Redis will be used to store, index, and query vector\n", + "embeddings created from PDF document chunks. **We need to make sure we have a Redis\n", + "instance available.\n", + "\n", + "#### For Colab\n", + "Use the shell script below to download, extract, and install [Redis Stack](https://redis.io/docs/getting-started/install-stack/) directly from the Redis package archive." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# NBVAL_SKIP\n", + "%%sh\n", + "curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg\n", + "echo \"deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main\" | sudo tee /etc/apt/sources.list.d/redis.list\n", + "sudo apt-get update > /dev/null 2>&1\n", + "sudo apt-get install redis-stack-server > /dev/null 2>&1\n", + "redis-stack-server --daemonize yes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### For Alternative Environments\n", + "There are many ways to get the necessary redis-stack instance running\n", + "1. On cloud, deploy a [FREE instance of Redis in the cloud](https://redis.com/try-free/). Or, if you have your\n", + "own version of Redis Enterprise running, that works too!\n", + "2. Per OS, [see the docs](https://redis.io/docs/latest/operate/oss_and_stack/install/install-stack/)\n", + "3. With docker: `docker run -d --name redis-stack-server -p 6379:6379 redis/redis-stack-server:latest`\n", + "\n", + "##### if running local version make sure to double check it is updated >=7.4\n", + "\n", + "### Define the Redis Connection URL\n", + "\n", + "By default this notebook connects to the local instance of Redis Stack. **If you have your own Redis Enterprise instance** - replace REDIS_PASSWORD, REDIS_HOST and REDIS_PORT values with your own." + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "\n", + "# Replace values below with your own if using Redis Cloud instance\n", + "REDIS_HOST = os.getenv(\"REDIS_HOST\", \"localhost\") # ex: \"redis-18374.c253.us-central1-1.gce.cloud.redislabs.com\"\n", + "REDIS_PORT = os.getenv(\"REDIS_PORT\", \"6379\") # ex: 18374\n", + "REDIS_PASSWORD = os.getenv(\"REDIS_PASSWORD\", \"\") # ex: \"1TNxTEdYRDgIDKM2gDfasupCADXXXX\"\n", + "\n", + "# If SSL is enabled on the endpoint, use rediss:// as the URL prefix\n", + "REDIS_URL = f\"redis://:{REDIS_PASSWORD}@{REDIS_HOST}:{REDIS_PORT}\"" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# from redis import Redis\n", + "import redis\n", + "\n", + "client = redis.Redis(\n", + " host='redis-11118.c309.us-east-2-1.ec2.redns.redis-cloud.com',\n", + " port=11118,\n", + " password='qt1Zl62JL07F7RTGac40XCiEhksh4xjD')\n", + "# client = Redis.from_url(REDIS_URL)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "client.ping()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Define index and load data\n", + "\n", + "We will be loading a schema of movie information with a 32bit float." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "\n", + "with open(\"resources/movies.json\", 'r') as file:\n", + " movies = json.load(file)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "07:32:48 redisvl.index.index INFO Index already exists, overwriting.\n" + ] + } + ], + "source": [ + "from redisvl.schema import IndexSchema\n", + "from redisvl.index import SearchIndex\n", + "\n", + "index_name = \"movies32\"\n", + "\n", + "schema = IndexSchema.from_dict({\n", + " \"index\": {\n", + " \"name\": index_name,\n", + " },\n", + " \"fields\": [\n", + " {\n", + " \"name\": \"title\",\n", + " \"type\": \"text\",\n", + " },\n", + " {\n", + " \"name\": \"description\",\n", + " \"type\": \"text\",\n", + " },\n", + " {\n", + " \"name\": \"genre\",\n", + " \"type\": \"tag\",\n", + " \"attrs\": {\n", + " \"sortable\": True\n", + " }\n", + " },\n", + " {\n", + " \"name\": \"rating\",\n", + " \"type\": \"numeric\",\n", + " \"attrs\": {\n", + " \"sortable\": True\n", + " }\n", + " },\n", + " {\n", + " \"name\": \"vector\",\n", + " \"type\": \"vector\",\n", + " \"attrs\": {\n", + " \"dims\": 384,\n", + " \"distance_metric\": \"cosine\",\n", + " \"algorithm\": \"hnsw\",\n", + " \"datatype\": \"float32\"\n", + " }\n", + " }\n", + " ]\n", + "})\n", + "\n", + "\n", + "index = SearchIndex(schema, client)\n", + "index.create(overwrite=True, drop=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Embed movie description vectors" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/robert.shelton/.pyenv/versions/3.11.9/lib/python3.11/site-packages/huggingface_hub/file_download.py:1132: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`.\n", + " warnings.warn(\n", + "/Users/robert.shelton/.pyenv/versions/3.11.9/lib/python3.11/site-packages/huggingface_hub/file_download.py:1132: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`.\n", + " warnings.warn(\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from sentence_transformers import SentenceTransformer\n", + "\n", + "# load model for embedding our movie descriptions\n", + "model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')\n", + "\n", + "def embed_text(model, text):\n", + " return np.array(model.encode(text)).astype(np.float32).tobytes()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# Note: convert embedding array to bytes for storage in Redis Hash data type\n", + "movie_data32 = [\n", + " {\n", + " **movie,\n", + " \"vector\": embed_text(model, movie[\"description\"])\n", + " } for movie in movies\n", + "]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Populate the index" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['rvl:37b42d13adaa4a4ea32db5e4d062126b',\n", + " 'rvl:9e3dfc7c67b744bb8199d364c60f8d89',\n", + " 'rvl:8f7758c7763842f78490e3c43aab1148',\n", + " 'rvl:c961854993a04d089da2e026033b80b3',\n", + " 'rvl:7f2699e7dbf3474283d34bf04b465f00',\n", + " 'rvl:cc56f14da1f8431c90a318167ce7e506',\n", + " 'rvl:5c0097099939492f87b2b56890bc7dfe',\n", + " 'rvl:6c215979299c424ebff07a4b85a60f43',\n", + " 'rvl:896cd78dae42483db66019f2b62a70e4',\n", + " 'rvl:b92104d038c04ab3beab80139f75e7d1',\n", + " 'rvl:17b08c1a64b743ecab2e5acaa4a777af',\n", + " 'rvl:d7e8d94d158e4003ad443ec5ce517f53',\n", + " 'rvl:a448ffc20ac8474ab776df5e54ae26a9',\n", + " 'rvl:87e2cd98e776411cb7f552a29a808a2a',\n", + " 'rvl:750ccddcf5604b12b33fb81e78042db0',\n", + " 'rvl:403fcaf607b04e5a9b7561a86082cb26',\n", + " 'rvl:12e4333184554daca7cbbf44e77ccb18',\n", + " 'rvl:5be2ed277c1c4f3b8afb929446afda9e',\n", + " 'rvl:6ccdd8c9eb1f433fa92c85f16d4351ff',\n", + " 'rvl:7ba0ee30d58f45e7bc1d5d21fbe9a45d']" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "keys = index.load(movie_data32)\n", + "keys" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "client.memory_usage('rvl:37f6b0ea780c4a84a156f35f54a31c7e')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Now let's convert to fp16\n", + "\n", + "This is as simple as you think it is using numpy." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "movie_data16 = []\n", + "for movie in movie_data32:\n", + " vect16 = np.frombuffer(movie[\"vector\"], dtype=np.float32).astype(np.float16)\n", + " movie[\"vector\"] = vect16.tobytes()\n", + " movie_data16.append(movie)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'title': 'Explosive Pursuit',\n", + " 'genre': 'action',\n", + " 'rating': 7,\n", + " 'description': 'A daring cop chases a notorious criminal across the city in a high-stakes game of cat and mouse.',\n", + " 'vector': b'\\xe3+S\\x18\\xbd\\x1d\\xf6\\xabs\\x9eQ*\\xfd)\\xac$8\\xb0{.\\x80+o\\xa8H\\xaa3&\\x0f+\\xb2\\xa0\\x9f \\xe5(O$n!\\xfe\\xa4\\x18\\xae\\x92*\\xbb\\xa7\\xba\\xb0)\\x88\\xfc%\\x17\\x93E\\xadg\\xa7+)\\x97\\x9b:*),\\x12\\xa5\\x83\\xaeY\\xaa\\xa7\\xa4G*1\"a\\'o\\xac\\xc3$\\x1d-\\x9b\\xa9\\xee\\xad\\xb9\\x1f\\xd8+f,0\\xae\\x82\\xac\\xe9\\x1dg\\xa8J\\xa6\\xe0\\xa5\\xa9\\x9bT&T*U)\\xaa\\xaa\\xb0\\xa4\\xc8(`\"N(d-\\xc7\\xad\\xe6\\xac\\xc4(3)\\xc2\\'H$\\x94\\x9f\\xda\\xaau\\x9f\\n\\xaa\\xcb\\xa8\\x93\\x9f\\xc6\\x1bz\"b\\xa1u-h\\xa1p\\xad\\xd7(n.\\x81)\\xf0\\xa4Z*\\x06)P\\xaa\\xf3\\x9c\\xbc\\x17\\xe8(\\xf6&\\xb3\\x98\\x83\\x9b\\xe7!\\x1d\\x85\\x9a#2!\\xc1 o\\xa9\\xc7$u*)-\\xf0&\\x9a p\\x96\\xe5\\xa6*(\\xad\\'\\x97\\xa2m\\xa1\\xe7\\nb/\\xb8*\\xb2\\xa6\\x99*\\xf7\\xaa\\x8d$\\x9f \\xce\\x9b|\\xa9\\x80#E\\x9c\\xef$\\xb0-\\x00\\x808\\x9d0\\xab[\\x9a\\x81\\x9c\\xcc\\x9d\\xce\\x9d[+h%C\\xadc.\\x07\\xb1z\\xa9\\xbb\\xa7\\xb5+\\x88#\\xe7\\xa8X$3\\xa54$\\xcc(%\\xa7\\xf3\\xa2s\\xa8\\x1e\\xa7\\xaa\\x1a\\xe2\\xab`\\xacT\\xa9\\xa4/\\x86\\x18q\\xa8\\xa7-\\xa9\\xa8\\x1c,\\xd1!\\x0f%h\\xacH\\xab\\xe8&\\xb4.\\xe5\\xac\\x0c\\xa9)\\x8e\\x9e\\xa4\\xf6\\xa91\\xaa\\xa2\\xb0D\\xa9J\\xac\\xa5&\\x19.x\\xaa\\x84\\xa3f\\xa5-\\xab\\x9c\\x1b\\x0b\\x1e\\x18\\xaa\\xf1\\x17\\xa7/Q!\\xe0(\\xb8\\xaao(7(\\xd4\\xad\\xb5&\\xcf\\x1ez).,\\x10){\\'\\x1f+B\\xb0\\xd9)\\xbb\\x1a\\x15#\\xbd%\\xdc\\xa9\\x8c\\xa4\\xe0\\xa9\\x19%*\\xa1\\xff\\x9d\\x94(\\xa9,\\xec\\xa7\\x90\\xae$\\x1c\\xa8+L#\\x95\\xaap\\xab\\x9e)7*\\x00\\x00\\xd2%}\\xaa8\\x1e(\\xa8\\x94\\xac\\'*\\xdf\\xa1\\xa2\\xa7\\xbc\\xack\\xa8\\xac\\xafA)6.\\xd7(\\xc5/v\\xa7\\xc1\\x98\\xdc!J\\xa8\\xb8(\\xf5(Z\\xaeh\\xack\\x9f\\xcb\\xa0\\x98\\xa0\\x1c,$\\xab\\x8e\\x9e\\xcb\\xa2\\x0c+\\xee\\xa7\\x1d\\x9c\\xca\\xa8\\xe8\\xaa\\xd7+\\xe2,K\\xad\\xcb\\xa1w\\xa2\\xc0\\xab\\x04-\\xb5$\\xc4\\x91\\xee\\xa9D!\\xa7\\x9d^\\xa8\\xa8\\xac\\xa6*\\x8c&:\\xa9@\"\\xc0%\\xeb\\xab\\x0c(\\xde\\xaa\\x1f {\\xa8<\\xa7A&\\xe0,7\\xad+/y\"\\x98)\\xb2\\xa9\\x97\\xa7;%\\x16\\xb0\\x93\\xa9T,N\\xa8n\\xa6o\\x9d\\xf8\\xa6)*\\xe8-i+s,%-U\\x9ej\\xa0\\xe2$s\\xacY+\\xf8\\x1d\\xf9\\'\\x92$b\\x1c\\x1d-\\xb1#\\x84\\x9f?\\xa0\\xed\\xa5\\x00\\x80\\x9c\\xaeW+?\\xad)\\'\\x81+\\xff,B\\xab\\xa5\\xaf?\\xa0W#\\xbc+\\x0f\\'\\xf5(\"&R #\\xa3h,4\\xa5i\\x96|.k\\xa9s+\\xf9\\xac\\xfc*\\x19!m\\x1b\\x04\\xb0\\\\\\xa4;*U.\\x8e\\xa3\\xd7\\xa9\\xed\"\\x8b\\x1es-\\x19\\xa8J,\\x9a\\xab\\x11+N\\x98@\\'&\\xa7\\x1b)\\\\\\xab\\x0b w\\xaa\\x88\\xa5P\\xaa\\xf8+\\xd7\\xaa\\x89\\x9f\\xc2)\\xa2\\xa2\\t$m*/ \\xe2\\xab\\xbd#?\\xad\\x03\\xa99(\\xa1\\xa0L\\'\\xb9,'}" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "movie_data16[0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Create new index" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "ename": "ValidationError", + "evalue": "1 validation error for IndexSchema\n__root__ -> attrs -> datatype\n value is not a valid enumeration member; permitted: 'FLOAT32', 'FLOAT64' (type=type_error.enum; enum_values=[, ])", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mValidationError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[12], line 6\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mredisvl\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mindex\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m SearchIndex\n\u001b[1;32m 4\u001b[0m index_name \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmovies16\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m----> 6\u001b[0m schema \u001b[38;5;241m=\u001b[39m \u001b[43mIndexSchema\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfrom_dict\u001b[49m\u001b[43m(\u001b[49m\u001b[43m{\u001b[49m\n\u001b[1;32m 7\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mindex\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43m{\u001b[49m\n\u001b[1;32m 8\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mname\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mindex_name\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 9\u001b[0m \u001b[43m \u001b[49m\u001b[43m}\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 10\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mfields\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43m[\u001b[49m\n\u001b[1;32m 11\u001b[0m \u001b[43m \u001b[49m\u001b[43m{\u001b[49m\n\u001b[1;32m 12\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mname\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtitle\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 13\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtype\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtext\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 14\u001b[0m \u001b[43m \u001b[49m\u001b[43m}\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 15\u001b[0m \u001b[43m \u001b[49m\u001b[43m{\u001b[49m\n\u001b[1;32m 16\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mname\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mdescription\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 17\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtype\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtext\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 18\u001b[0m \u001b[43m \u001b[49m\u001b[43m}\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 19\u001b[0m \u001b[43m \u001b[49m\u001b[43m{\u001b[49m\n\u001b[1;32m 20\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mname\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mgenre\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 21\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtype\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtag\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 22\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mattrs\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43m{\u001b[49m\n\u001b[1;32m 23\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43msortable\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\n\u001b[1;32m 24\u001b[0m \u001b[43m \u001b[49m\u001b[43m}\u001b[49m\n\u001b[1;32m 25\u001b[0m \u001b[43m \u001b[49m\u001b[43m}\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 26\u001b[0m \u001b[43m \u001b[49m\u001b[43m{\u001b[49m\n\u001b[1;32m 27\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mname\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mrating\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 28\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtype\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mnumeric\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 29\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mattrs\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43m{\u001b[49m\n\u001b[1;32m 30\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43msortable\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\n\u001b[1;32m 31\u001b[0m \u001b[43m \u001b[49m\u001b[43m}\u001b[49m\n\u001b[1;32m 32\u001b[0m \u001b[43m \u001b[49m\u001b[43m}\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 33\u001b[0m \u001b[43m \u001b[49m\u001b[43m{\u001b[49m\n\u001b[1;32m 34\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mname\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mvector\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 35\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtype\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mvector\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 36\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mattrs\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43m{\u001b[49m\n\u001b[1;32m 37\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mdims\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m384\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 38\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mdistance_metric\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mcosine\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 39\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43malgorithm\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mhnsw\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 40\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mdatatype\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mfloat16\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m 41\u001b[0m \u001b[43m \u001b[49m\u001b[43m}\u001b[49m\n\u001b[1;32m 42\u001b[0m \u001b[43m \u001b[49m\u001b[43m}\u001b[49m\n\u001b[1;32m 43\u001b[0m \u001b[43m \u001b[49m\u001b[43m]\u001b[49m\n\u001b[1;32m 44\u001b[0m \u001b[43m}\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 47\u001b[0m index \u001b[38;5;241m=\u001b[39m SearchIndex(schema, client)\n\u001b[1;32m 48\u001b[0m index\u001b[38;5;241m.\u001b[39mcreate(overwrite\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m, drop\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/lib/python3.11/site-packages/redisvl/schema/schema.py:263\u001b[0m, in \u001b[0;36mIndexSchema.from_dict\u001b[0;34m(cls, data)\u001b[0m\n\u001b[1;32m 227\u001b[0m \u001b[38;5;129m@classmethod\u001b[39m\n\u001b[1;32m 228\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mfrom_dict\u001b[39m(\u001b[38;5;28mcls\u001b[39m, data: Dict[\u001b[38;5;28mstr\u001b[39m, Any]) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mIndexSchema\u001b[39m\u001b[38;5;124m\"\u001b[39m:\n\u001b[1;32m 229\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Create an IndexSchema from a dictionary.\u001b[39;00m\n\u001b[1;32m 230\u001b[0m \n\u001b[1;32m 231\u001b[0m \u001b[38;5;124;03m Args:\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 261\u001b[0m \u001b[38;5;124;03m })\u001b[39;00m\n\u001b[1;32m 262\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m--> 263\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mcls\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mdata\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/lib/python3.11/site-packages/pydantic/v1/main.py:341\u001b[0m, in \u001b[0;36mBaseModel.__init__\u001b[0;34m(__pydantic_self__, **data)\u001b[0m\n\u001b[1;32m 339\u001b[0m values, fields_set, validation_error \u001b[38;5;241m=\u001b[39m validate_model(__pydantic_self__\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__class__\u001b[39m, data)\n\u001b[1;32m 340\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m validation_error:\n\u001b[0;32m--> 341\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m validation_error\n\u001b[1;32m 342\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 343\u001b[0m object_setattr(__pydantic_self__, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m__dict__\u001b[39m\u001b[38;5;124m'\u001b[39m, values)\n", + "\u001b[0;31mValidationError\u001b[0m: 1 validation error for IndexSchema\n__root__ -> attrs -> datatype\n value is not a valid enumeration member; permitted: 'FLOAT32', 'FLOAT64' (type=type_error.enum; enum_values=[, ])" + ] + } + ], + "source": [ + "from redisvl.schema import IndexSchema\n", + "from redisvl.index import SearchIndex\n", + "\n", + "index_name = \"movies16\"\n", + "\n", + "# this won't work till we merge Justin's stuff\n", + "schema = IndexSchema.from_dict({\n", + " \"index\": {\n", + " \"name\": index_name,\n", + " },\n", + " \"fields\": [\n", + " {\n", + " \"name\": \"title\",\n", + " \"type\": \"text\",\n", + " },\n", + " {\n", + " \"name\": \"description\",\n", + " \"type\": \"text\",\n", + " },\n", + " {\n", + " \"name\": \"genre\",\n", + " \"type\": \"tag\",\n", + " \"attrs\": {\n", + " \"sortable\": True\n", + " }\n", + " },\n", + " {\n", + " \"name\": \"rating\",\n", + " \"type\": \"numeric\",\n", + " \"attrs\": {\n", + " \"sortable\": True\n", + " }\n", + " },\n", + " {\n", + " \"name\": \"vector\",\n", + " \"type\": \"vector\",\n", + " \"attrs\": {\n", + " \"dims\": 384,\n", + " \"distance_metric\": \"cosine\",\n", + " \"algorithm\": \"hnsw\",\n", + " \"datatype\": \"float16\"\n", + " }\n", + " }\n", + " ]\n", + "})\n", + "\n", + "\n", + "index = SearchIndex(schema, client)\n", + "index.create(overwrite=True, drop=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "from redis.commands.search.field import VectorField, TagField, NumericField, TextField\n", + "from redis.commands.search.indexDefinition import IndexDefinition, IndexType\n", + "\n", + "index_name = \"movies\"\n", + "\n", + "schema = (\n", + " VectorField(\n", + " \"vector\",\n", + " \"HNSW\",\n", + " {\n", + " \"TYPE\": \"FLOAT16\",\n", + " \"DIM\": 384,\n", + " \"DISTANCE_METRIC\": \"COSINE\"\n", + " }\n", + " ),\n", + " NumericField(\"rating\"),\n", + " TagField(\"genre\"),\n", + " TextField(\"title\"),\n", + " TextField(\"description\")\n", + ")\n", + "\n", + "try:\n", + " client.ft(index_name).info()\n", + " print(\"Index exists!\")\n", + "except:\n", + " # index Definition\n", + " definition = IndexDefinition(index_type=IndexType.HASH)\n", + "\n", + " # create Index\n", + " client.ft(index_name).create_index(fields=schema, definition=definition)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "def load_docs(client: redis.Redis, data: list[dict]):\n", + " for i, d in enumerate(data):\n", + " client.hset(\n", + " i,\n", + " mapping = d\n", + " )\n", + "\n", + "def print_results(res):\n", + " docs = [(doc.title, doc.genre, doc.rating) for doc in res.docs]\n", + " print(f\"Top {len(docs)} movies: \", docs)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "load_docs(client, movie_data16)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Result{20 total, docs: [Document {'id': '0', 'payload': None, 'title': 'Explosive Pursuit', 'genre': 'action', 'description': 'A daring cop chases a notorious criminal across the city in a high-stakes game of cat and mouse.', 'vector': '+S\\x18\\x1dsQ*)$8{.+oH3&\\x0f+ (O$n!\\x18*)%\\x17Eg+):*),\\x12YG*1\"a\\'o$\\x1d-\\ueb79\\x1f+f,0\\x1dgJ३T&T*U)(`\"N(d-ǭ(3)\\'H$ڪu\\n˨\\x1bz\"bu-hp(n.)Z*\\x06)P\\x17(&!\\x1d#2! o$u*)-& p*(\\'m\\nb/**$ Λ|#E$-\\x0080[̝Ν[+h%Cc.\\x07z+#X$34$(%s\\x1e\\x1a`T/\\x18q-\\x1c,!\\x0f%hH&.\\x0c)1DJ&\\x19.xf-\\x1b\\x0b\\x1e\\x18\\x17/Q!(o(7(ԭ&\\x1ez).,\\x10){\\'\\x1f+B)\\x1a\\x15#%ܩ\\x19%*(,짐$\\x1c+L#p)7*\\x00\\x00%}8\\x1e(\\'*ߡkA)6.(/v!J((Zhkˠ\\x1c,$ˢ\\x0c+\\x1dʨ+,Kˡw\\x04-$đD!^*&:@\"%\\x0c(ު\\x1f {\\x07(.\\x1c@.\\x1e[)߬,\"5(\\x1f([\\x00|7\\x1e+19A-\\x16%\\x1f$\\x08,KX\\x1d*.m-ۢ寋\\x1f)\\x17v(*\"3%N)&\\x1f\\x1f\\x02\\x15\\x04\\x16,\\x9ey!Z+\\x12|\\x08$Uz%\\x1cRh\\x0c\\x18(#N\\x1dGJdÕX\\x0c\\x19蜗./\\x1b\"̘%)b+**.Ϫ\\x00 @,_-\\x042y+.1\\x1fS{)d\\x00\\x00o\\x1eɪ:\\x7f,\\x08w\"] \\x1c.W\\'!\\x00)Ѧ\\x06\\'\\x04-\\x1b\\x17.L %\\x1c,6$+M\\x1du\\x1f\\'e0#*(z)V,$\\x02ܬ\"&p%\\r2\\x1f-D\\'t*9\\x03ά%˩%$\\x1aW)%,<\\x15,!%\\x1f!k\\x1e&\\x16*)\\x17\\x1e((u*(>\\x03[\\x1cc,%\\x003p(w*\\x16\\x1f4 =)+]\\x14\\x18\\x1a#\\x1e,G\\x1f!\\'ڦ\\',\\x1c\\x1f)\\t$j/)N)\\x16(\\x0co+t? \\x06.-ר+\\x18,\\x18ԫf*O)\\n kũ`*)\\x0f\\'m\\\\%B#\\x17)', 'rating': '8'}, Document {'id': '2', 'payload': None, 'title': 'Fast & Furious 9', 'genre': 'action', 'description': 'Dom and his crew face off against a high-tech enemy with advanced weapons and technology.', 'vector': '=\\x11-A\\x1d*+\\x01-g4);(m+\\x1c\\rT,\\x1e+b#\\x1bء(\\x18\\x00.q-uڥL(֦\\x08>}-\\x1d*O¬P \\x18\\x05)J\\x1a,\\x1b*!)\\x19&\\x14R,A#Wo&ʡA+\\r+),-\\x1dU#ߤ&&\\x1fᗬ/۩?*3˕~+Ȩ._)s&\\x02.\\x1c\\x11-,$%<+)\\x04\\'(,d$1g3*![%8\\t5)V1(LӨ|.-*\\x00\\x19\"Z+(* c-\\x19ǩ$A\\x1d\\x1c*ޣ\\t\\x16M\\'#E%,l\\x155\\x1f)-\\x00\\x15,\\x10*1-(ͥȫj\\x11I$\\x13\\'\"+\\x19%˨#\\'\\'\\'\\u2438-(**,*˦[t)r\\x02)H*U(먤%p\"$#$\\x1b$\\x0eb\\'AC)?\\x1aD\\x14dާ\\x00\\x008b& u*z\\x1f,+],)Bp5r,\\x0c\\x12,S\\x1c(1y\\',)Z*p(\\x19+\\x07$e 0*ө_\\x0b,Ĥ~7.vQ\\x1c\\x15&~) c,G,\\x1b!;*\\x07\\x1d\\x10(J-\\x1b,/.ά*ik) \\x1cp*k(\\x1e¨-)c/ɝ\\x12\\\\w{\\x1f\\x1c9\\x00dG\\x01\\x1f&۩h,A\\x1d$ -h\\'R+,\\x0bcԮ\\x08\\x1d).(o%-z&,-; \\x1c0\\x13*Μ,ҭ*H\\'v,K-\\x90\\x02\\x13\\x1d\\x04)$-Ir$B 9\\x15,R(', 'rating': '6'}, Document {'id': '3', 'payload': None, 'title': 'Black Widow', 'genre': 'action', 'description': 'Natasha Romanoff confronts her dark past and family ties as she battles a new enemy.', 'vector': '/~\\x17+%\\x04-Z(Δ\\x1f?\\x1c\\x16$6:B\\x14$\\x1c\\r\\x1ff\\x0b#)\\x06\\'(6\\x1c&\\x13),\"&$*-y)&)E*R\\x00u\\x16$.\\x1d\\x07\\x14V\\x1dXn)-.)\\x1d\\'\\'*]J\\x13)\\'%{,Y\\x07*+D˪\\x11..(%\\x15))\"M!(\\x17\\n!R+\\x02E\\x1f ^,\\'&Ց$\\x10**\\x0f1(ڨ)rڬ)+&\\x17.\\x01 /\\x18oK,J)[*\\x06%T\\x1f8\\x00N#%K\\x16/(!)r(}\\x1eV,x`)d*j(#/z\\x1d/0\\x13?ӧ\\n(6(}$*%\\'-$d*\\'(\\x06\\x14\\x1e\\x13`(JY4#v,4T!<\\x02\\x00*$\\x17-\\'i5*\\x14+\\x18\\x19ҥi&($.\\x1c t\\x1a!)\\x0f,6۬7\\'A*\\x04\\x1f\\x08(\\x02\\x05)|&\\x00-k\\x7f&,⡡X.P!\\x0b)!(2(#Ѫ.\\x1e\\x94\\x10\\x1a\\x06`,j0}\\x15oG\\x06\\x1b\\'*0*ˮ\\'$8\\x0b-?-m/u)0\\x0eXt*~,ί)\\x1f,/D\\x10%v\\x00zl\\x1f٩j-̦2\\x1b,]$\\x0b\\'$)F\\',\\x13/&}.E(gK\\x14L\\x00硇R\\'Ȭժ+\\x1bb\\x1a\\x1d*\\x05\"j)#Ϊ1.k-7we\\x13\\x05\\'g\\x15rΥ\\t,)%!Ҩy-%f\\x1fwg*P,hRw\"*+1<\\x18\\x1c\\x1a)m(8)\"\\x0c*%,h*U', 'rating': '7'}, Document {'id': '4', 'payload': None, 'title': 'John Wick', 'genre': 'action', 'description': 'A retired hitman seeks vengeance against those who wronged him, leaving a trail of destruction in his wake.', 'vector': '\\x9b).\\x19$\\x1b\\r#Mդk\\'\\x03H(p\\x1f%2$.l$@:-/\\x11QSѥ\\x03*%թţ\\x1cޭO$*H#%%h$ʩ\\x0f!C+\\x00*fa((h(kx-y\\x1ch*ĢQ()d%\\\\,U(j,)E$\\x0e|$%,Q!^-* #*K+)$%1\\x10,˧*k.؟l5#()$ѯ\\x15,\\x0eϘd(\\x1c,窺;,4(!k\\x1d\\x19,\\x1d\\x00(&& \\x00y,#\\n\\'w%\\x16&a)&*y\\x11/$\"?#,ެP\\x08.ǥ(\\x17g#(5xi/,U*!#a(u(\\x0c\\x16\\x19T$.h1!0%%w\\x01,[\">N\\'A(4\\x19+\\x03Y\\x1f.\"\\x1e\\n:\\x1d-<\\x1e)\\x00P)D*ڦ\\x15%&ʨե&\\'\\x05\\x01\\t&+$$p,=\\x00\\x18#\\')\\x03,\\x1e,,t4>1/\\x1f#\\x10QM\"=-\\x0b̟],2\\x0b#)H-9.& V#h\\x1e\\'$\\x02$+0\\x16+.\\x06)\\'\\'-\\'d*E\\x1eŬ \\x061\\x14R)ƩVW*\\x10XI&ͫ\\x04\"#\\'ҭ\\x17,\\x0f\\x1fB)#\\'!ӟ\\x00\\x04ꕔ%\\x12 +!]m*\\x19%o--s\\x1e$(Nάܪ\\x1cq\"(,N*&\\x1eB) \\x0e(y%p)+\\x10?A,(\\'3ǮW $wt)+\"\\x0c)t)yY(!Ƥ0\\x0536\"', 'rating': '8'}, Document {'id': '6', 'payload': None, 'title': 'The Dark Knight', 'genre': 'action', 'description': 'Batman faces off against the Joker, a criminal mastermind who threatens to plunge Gotham into chaos.', 'vector': '\\n/)j &*,\\'l$rR(\\x1d;ѥZ%, (*]-|\\x1f\\x03k+v(+$\\x1d)֭(6#բ0E+0() =&$9Y+*}\\x12+m(\\x1c(\\x11$I!V.()\"\\'l)J),\\x12*O Р,V\\'X$Ϥ&\\'\\x1a,\\x11\\')\\'N*ʠ1\\'\\x1c-::DJ)%\\'}(4\\x1fg\\'+S\\x08\\\\\\x07-\\x1f\\x10 !,*L)0**d),\\n--G!\\x15O)[Ȫ\\x00u\\x05\\x11T,fS%8)0!ps0e\\x07,\\x0c\\'7\\x0e\\x19g\\x08 g%\\x04\"(l*#R-c_)G)*\\x1adĭM\\x15̨߬#y ($쬮#9~)S\\x7f\\x0b#*\\x1fr\\x1fǡ5T\"+\\x19\"4\\'\\x17),\\x7fQ*d)\\t/T\\n\\x1c#ҭ¬\\r%\\x19s)릶(j*\\x00&@q9#\\x1dʬ*Y\\x1f8,(,*+\\x14)H&Eȡ\\x01\\n\\x17*#!\\t*l&(&((0gJ+\\x02)x\\x1c*\\x0f+Z.<(\\r(a$\\n( r`\\x1d}\\x11]1\\')N*\\x14%u+d(/\\x18\\x1fz\\x07ު\\r)!דɧ$+?(\\x10.\\x1f\\x12*\\x07*\\x05+%\\x00T˪]!\\x03$s+;Il*x%t% ,Z\\x06\\x0f=\\x18ȮC >\\',*ߣ3,\\x1a/*R$(t,ǩ\\\\$*~(;+2K& \\x1c\"uT\\x1d\\\\\\x11)Pfz$M)\\x15,\\x0b*b\\x1e', 'rating': '9'}, Document {'id': '7', 'payload': None, 'title': 'Gladiator', 'genre': 'action', 'description': 'A betrayed Roman general seeks revenge against the corrupt emperor who murdered his family.', 'vector': '.+\\x93;m^)\\x7f*\\x19\\x1a*3#\\x01\\x02.~$\\x02+$\\x1f|)e+X\\x04\\x04(C7,p\\x05\\x05M|+%.\\'*.50\\'~+(*$\\'t&\\x1a\\x11.\\x01\\x12\\'Ц+ (,\\x13\\'\\x1aWX\\';? \\x1c/Z+x\\x1d\\x1c\\x1a)\\x0f%jqT\\x14s*7\\x1e[*Fo,\\x0c0*hW*̠]-++h(o\\x1ebh)*\\x16\\x003\\x1clb!)*\\x0b\\x1dy.\\x1f@+,vV.,\\x197&(%[\\x1dQ(&\\'-(I#E!0$ЬU.X(-t(\\x1c&z$jED\\x1c(,$;\\x1cP*))\"),\\',(`^a$M5,\\x13\\x18a|(W9Ԯ\\x1e#i$\"\\x9d\\x08ޙ*\\x03!sì.l\\x00S\\x1f\\n$*\\x07!2k7\\'\\x1a$],V(ɪP0%##\\x1fj&\"z\\x0f).((,\\x0f,P#\\x01(G\\x1c./,\\x0bҡ$,\\'j,-˦)\\x08&h\\')&.\\x08.k(.v$̦\\'T\\x10$-Q(:r!(\\x07%O\\x1e\\'!,f-)*A\\x0f)B%t*}\\x0f,\\n.\\x1b-c\\x0c( .})\\x00\\x0c9&7\\x0f֬\\x1b\\x1f,!+\\r,\\x16%\\x1e\\\\\\x1cX\\x16\\x0f\\'ĥ\\x00-G\"\\x1e٥V, *̠!U,|+X\\',&m\\x02\\x01*,ʤQ\\x1d%,l\\x1a\\x15o*\\x12.(w#e\\x14', 'rating': '8'}, Document {'id': '8', 'payload': None, 'title': 'Inception', 'genre': 'action', 'description': 'A thief who enters dreams to steal secrets faces his toughest mission yet, with reality itself at stake.', 'vector': '**6$\\x18!\"&T+\\x1d١.$\"\\x0e3(%\\x01&*1\\x02**d\\')Щ\\uf805\\x1a-1*%+7էC \\x1c+ܡߡ\\x0f$\\x07**$~\\x1d(+ܫw($)[-\\x17\\x04+\\x0f(G2X-\\x1a+ףsp$%,hIf\\'\\x1cOg!-LA\\x10\\x0b#;\\n\\x03XR&,N-+Jx\\x1f;\\x00ܠ*!?#d(a&iAw\\x15Q.|\\'4*_8,a\\x14/Q8\\x0c*E9\\x1dW)m\\x1b\\x1d,N*&*-K*Wjh2\\'\\x11\\x15g&(\\x10)(\\x1aR\\x16\\x14\\x11),\\x00)9-\\x19*\\x17\\x19#-˨4\\x1aK\\x07ΩݦO&\\x02,\\x1f\\x0b7\\x05x(!\"-g%q\\x03@)\\':\\x07$\\x1d\\x00j-\\x16x\\'r,\\t,7\"\\x1e}*%)/\\r\\n*\\x06q #((\\n(N,o\\x16NE\\x1f߭M%aO-I[\\'y\\x11ħh\\\\\\\\,\\x1c,,\\x00-h)F)\\x03$\\x1b&s\\x1b()@+n%R\")(%`!.\\r)6-\\x11B&.!A((\\x13\\x1c,%J>*N(.ɫ\\x1b\\x08t$S\\x00{2+n*\\x02&W1K,*p\\'g)\\x19\\x18Ț)#-\"~\\'m# X0[&ɪd(\\x0e%6+)D&\\x13,\\x1d(,(\\x7f䧨,ʫ+\\x1eS\\'?\\x18\\x04-,m$M#4(^[\\x1c+\\x05\"\\x15\\x01', 'rating': '9'}, Document {'id': '9', 'payload': None, 'title': 'The Avengers', 'genre': 'action', 'description': \"Earth's mightiest heroes come together to stop an alien invasion that threatens the entire planet.\", 'vector': '&\\')\\x1b-0¨ȧ,=)\\x1c㞌)O\\x18\\'yu/4(-g+P!c\\x12\\x1dԧt$1\\x03*| m*\\x0fX&Ȭ[\\x1e\\x04\\x1cŬaC#p\\'Ϣ߫,w**\\x14ᠸ\\x1f$˥\\x1ff\\x1b*/\\x0c)\"\\x15<\\x14zc+,9%\\',[]&a\\x16@)4+$`-C+*ӣҪ&: w\\x195F&p \\x7f\\x1d>*0x*B\\x1d`**,)0\\x04\\t*$\\x07)|,x\\x12\\x00G\\x1b\\x1f(\\x1e&l\\x04-)C#_=)\\x0e(\\x1e$i(6\"C4\\x7f+\\x11(\\x03#!,Ξ\\x13J,Q-\"$&?(h+T,S\\x0c,j$d&+XT!f!\\x1b\\'\\x0c\\x1b%\\x18*\\x05+X)\\x1cΰ-%@\\x1f{--04\\t&$(\"X$w)\\x1cy zZ)y$)\\x02K\\x00\\x00˨\\x04\\x1a)\\x00/+)kr*\\x0f,\\x14?,:/\"M&`-(#\\ue840,#((@(\\x160\\x00-e!}C>\"()\\'\\x05+\\',\\x1d,\\x04w),m(a=+\\x1a-*\\'X,(\\x16ק!a,\\x18*+៥ڨs)\\x15?u\\x13$l\\x00~\\x1c,HX)(', 'rating': '8'}]}" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "res = client.ft(index_name).search(\"*\")\n", + "res" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Document {'id': '0', 'payload': None, 'title': 'Explosive Pursuit', 'genre': 'action', 'description': 'A daring cop chases a notorious criminal across the city in a high-stakes game of cat and mouse.', 'vector': '+S\\x18\\x1dsQ*)$8{.+oH3&\\x0f+ (O$n!\\x18*)%\\x17Eg+):*),\\x12YG*1\"a\\'o$\\x1d-\\ueb79\\x1f+f,0\\x1dgJ३T&T*U)(`\"N(d-ǭ(3)\\'H$ڪu\\n˨\\x1bz\"bu-hp(n.)Z*\\x06)P\\x17(&!\\x1d#2! o$u*)-& p*(\\'m\\nb/**$ Λ|#E$-\\x0080[̝Ν[+h%Cc.\\x07z+#X$34$(%s\\x1e\\x1a`T/\\x18q-\\x1c,!\\x0f%hH&.\\x0c)1DJ&\\x19.xf-\\x1b\\x0b\\x1e\\x18\\x17/Q!(o(7(ԭ&\\x1ez).,\\x10){\\'\\x1f+B)\\x1a\\x15#%ܩ\\x19%*(,짐$\\x1c+L#p)7*\\x00\\x00%}8\\x1e(\\'*ߡkA)6.(/v!J((Zhkˠ\\x1c,$ˢ\\x0c+\\x1dʨ+,Kˡw\\x04-$đD!^*&:@\"%\\x0c(ު\\x1f {\\x07(.\\x1c@.\\x1e[)߬,\"5(\\x1f([\\x00|7\\x1e+19A-\\x16%\\x1f$\\x08,KX\\x1d*.m-ۢ寋\\x1f)\\x17v(*\"3%N)&\\x1f\\x1f\\x02\\x15\\x04\\x16,\\x9ey!Z+\\x12|\\x08$Uz%\\x1cRh\\x0c\\x18(#N\\x1dGJdÕX\\x0c\\x19蜗./\\x1b\"̘%)b+**.Ϫ\\x00 @,_-\\x042y+.1\\x1fS{)d\\x00\\x00o\\x1eɪ:\\x7f,\\x08w\"] \\x1c.W\\'!\\x00)Ѧ\\x06\\'\\x04-\\x1b\\x17.L %\\x1c,6$+M\\x1du\\x1f\\'e0#*(z)V,$\\x02ܬ\"&p%\\r2\\x1f-D\\'t*9\\x03ά%˩%$\\x1aW)%,<\\x15,!%\\x1f!k\\x1e&\\x16*)\\x17\\x1e((u*(>\\x03[\\x1cc,%\\x003p(w*\\x16\\x1f4 =)+]\\x14\\x18\\x1a#\\x1e,G\\x1f!\\'ڦ\\',\\x1c\\x1f)\\t$j/)N)\\x16(\\x0co+t? \\x06.-ר+\\x18,\\x18ԫf*O)\\n kũ`*)\\x0f\\'m\\\\%B#\\x17)', 'rating': '8'},\n", + " Document {'id': '2', 'payload': None, 'title': 'Fast & Furious 9', 'genre': 'action', 'description': 'Dom and his crew face off against a high-tech enemy with advanced weapons and technology.', 'vector': '=\\x11-A\\x1d*+\\x01-g4);(m+\\x1c\\rT,\\x1e+b#\\x1bء(\\x18\\x00.q-uڥL(֦\\x08>}-\\x1d*O¬P \\x18\\x05)J\\x1a,\\x1b*!)\\x19&\\x14R,A#Wo&ʡA+\\r+),-\\x1dU#ߤ&&\\x1fᗬ/۩?*3˕~+Ȩ._)s&\\x02.\\x1c\\x11-,$%<+)\\x04\\'(,d$1g3*![%8\\t5)V1(LӨ|.-*\\x00\\x19\"Z+(* c-\\x19ǩ$A\\x1d\\x1c*ޣ\\t\\x16M\\'#E%,l\\x155\\x1f)-\\x00\\x15,\\x10*1-(ͥȫj\\x11I$\\x13\\'\"+\\x19%˨#\\'\\'\\'\\u2438-(**,*˦[t)r\\x02)H*U(먤%p\"$#$\\x1b$\\x0eb\\'AC)?\\x1aD\\x14dާ\\x00\\x008b& u*z\\x1f,+],)Bp5r,\\x0c\\x12,S\\x1c(1y\\',)Z*p(\\x19+\\x07$e 0*ө_\\x0b,Ĥ~7.vQ\\x1c\\x15&~) c,G,\\x1b!;*\\x07\\x1d\\x10(J-\\x1b,/.ά*ik) \\x1cp*k(\\x1e¨-)c/ɝ\\x12\\\\w{\\x1f\\x1c9\\x00dG\\x01\\x1f&۩h,A\\x1d$ -h\\'R+,\\x0bcԮ\\x08\\x1d).(o%-z&,-; \\x1c0\\x13*Μ,ҭ*H\\'v,K-\\x90\\x02\\x13\\x1d\\x04)$-Ir$B 9\\x15,R(', 'rating': '6'},\n", + " Document {'id': '3', 'payload': None, 'title': 'Black Widow', 'genre': 'action', 'description': 'Natasha Romanoff confronts her dark past and family ties as she battles a new enemy.', 'vector': '/~\\x17+%\\x04-Z(Δ\\x1f?\\x1c\\x16$6:B\\x14$\\x1c\\r\\x1ff\\x0b#)\\x06\\'(6\\x1c&\\x13),\"&$*-y)&)E*R\\x00u\\x16$.\\x1d\\x07\\x14V\\x1dXn)-.)\\x1d\\'\\'*]J\\x13)\\'%{,Y\\x07*+D˪\\x11..(%\\x15))\"M!(\\x17\\n!R+\\x02E\\x1f ^,\\'&Ց$\\x10**\\x0f1(ڨ)rڬ)+&\\x17.\\x01 /\\x18oK,J)[*\\x06%T\\x1f8\\x00N#%K\\x16/(!)r(}\\x1eV,x`)d*j(#/z\\x1d/0\\x13?ӧ\\n(6(}$*%\\'-$d*\\'(\\x06\\x14\\x1e\\x13`(JY4#v,4T!<\\x02\\x00*$\\x17-\\'i5*\\x14+\\x18\\x19ҥi&($.\\x1c t\\x1a!)\\x0f,6۬7\\'A*\\x04\\x1f\\x08(\\x02\\x05)|&\\x00-k\\x7f&,⡡X.P!\\x0b)!(2(#Ѫ.\\x1e\\x94\\x10\\x1a\\x06`,j0}\\x15oG\\x06\\x1b\\'*0*ˮ\\'$8\\x0b-?-m/u)0\\x0eXt*~,ί)\\x1f,/D\\x10%v\\x00zl\\x1f٩j-̦2\\x1b,]$\\x0b\\'$)F\\',\\x13/&}.E(gK\\x14L\\x00硇R\\'Ȭժ+\\x1bb\\x1a\\x1d*\\x05\"j)#Ϊ1.k-7we\\x13\\x05\\'g\\x15rΥ\\t,)%!Ҩy-%f\\x1fwg*P,hRw\"*+1<\\x18\\x1c\\x1a)m(8)\"\\x0c*%,h*U', 'rating': '7'},\n", + " Document {'id': '4', 'payload': None, 'title': 'John Wick', 'genre': 'action', 'description': 'A retired hitman seeks vengeance against those who wronged him, leaving a trail of destruction in his wake.', 'vector': '\\x9b).\\x19$\\x1b\\r#Mդk\\'\\x03H(p\\x1f%2$.l$@:-/\\x11QSѥ\\x03*%թţ\\x1cޭO$*H#%%h$ʩ\\x0f!C+\\x00*fa((h(kx-y\\x1ch*ĢQ()d%\\\\,U(j,)E$\\x0e|$%,Q!^-* #*K+)$%1\\x10,˧*k.؟l5#()$ѯ\\x15,\\x0eϘd(\\x1c,窺;,4(!k\\x1d\\x19,\\x1d\\x00(&& \\x00y,#\\n\\'w%\\x16&a)&*y\\x11/$\"?#,ެP\\x08.ǥ(\\x17g#(5xi/,U*!#a(u(\\x0c\\x16\\x19T$.h1!0%%w\\x01,[\">N\\'A(4\\x19+\\x03Y\\x1f.\"\\x1e\\n:\\x1d-<\\x1e)\\x00P)D*ڦ\\x15%&ʨե&\\'\\x05\\x01\\t&+$$p,=\\x00\\x18#\\')\\x03,\\x1e,,t4>1/\\x1f#\\x10QM\"=-\\x0b̟],2\\x0b#)H-9.& V#h\\x1e\\'$\\x02$+0\\x16+.\\x06)\\'\\'-\\'d*E\\x1eŬ \\x061\\x14R)ƩVW*\\x10XI&ͫ\\x04\"#\\'ҭ\\x17,\\x0f\\x1fB)#\\'!ӟ\\x00\\x04ꕔ%\\x12 +!]m*\\x19%o--s\\x1e$(Nάܪ\\x1cq\"(,N*&\\x1eB) \\x0e(y%p)+\\x10?A,(\\'3ǮW $wt)+\"\\x0c)t)yY(!Ƥ0\\x0536\"', 'rating': '8'},\n", + " Document {'id': '6', 'payload': None, 'title': 'The Dark Knight', 'genre': 'action', 'description': 'Batman faces off against the Joker, a criminal mastermind who threatens to plunge Gotham into chaos.', 'vector': '\\n/)j &*,\\'l$rR(\\x1d;ѥZ%, (*]-|\\x1f\\x03k+v(+$\\x1d)֭(6#բ0E+0() =&$9Y+*}\\x12+m(\\x1c(\\x11$I!V.()\"\\'l)J),\\x12*O Р,V\\'X$Ϥ&\\'\\x1a,\\x11\\')\\'N*ʠ1\\'\\x1c-::DJ)%\\'}(4\\x1fg\\'+S\\x08\\\\\\x07-\\x1f\\x10 !,*L)0**d),\\n--G!\\x15O)[Ȫ\\x00u\\x05\\x11T,fS%8)0!ps0e\\x07,\\x0c\\'7\\x0e\\x19g\\x08 g%\\x04\"(l*#R-c_)G)*\\x1adĭM\\x15̨߬#y ($쬮#9~)S\\x7f\\x0b#*\\x1fr\\x1fǡ5T\"+\\x19\"4\\'\\x17),\\x7fQ*d)\\t/T\\n\\x1c#ҭ¬\\r%\\x19s)릶(j*\\x00&@q9#\\x1dʬ*Y\\x1f8,(,*+\\x14)H&Eȡ\\x01\\n\\x17*#!\\t*l&(&((0gJ+\\x02)x\\x1c*\\x0f+Z.<(\\r(a$\\n( r`\\x1d}\\x11]1\\')N*\\x14%u+d(/\\x18\\x1fz\\x07ު\\r)!דɧ$+?(\\x10.\\x1f\\x12*\\x07*\\x05+%\\x00T˪]!\\x03$s+;Il*x%t% ,Z\\x06\\x0f=\\x18ȮC >\\',*ߣ3,\\x1a/*R$(t,ǩ\\\\$*~(;+2K& \\x1c\"uT\\x1d\\\\\\x11)Pfz$M)\\x15,\\x0b*b\\x1e', 'rating': '9'},\n", + " Document {'id': '7', 'payload': None, 'title': 'Gladiator', 'genre': 'action', 'description': 'A betrayed Roman general seeks revenge against the corrupt emperor who murdered his family.', 'vector': '.+\\x93;m^)\\x7f*\\x19\\x1a*3#\\x01\\x02.~$\\x02+$\\x1f|)e+X\\x04\\x04(C7,p\\x05\\x05M|+%.\\'*.50\\'~+(*$\\'t&\\x1a\\x11.\\x01\\x12\\'Ц+ (,\\x13\\'\\x1aWX\\';? \\x1c/Z+x\\x1d\\x1c\\x1a)\\x0f%jqT\\x14s*7\\x1e[*Fo,\\x0c0*hW*̠]-++h(o\\x1ebh)*\\x16\\x003\\x1clb!)*\\x0b\\x1dy.\\x1f@+,vV.,\\x197&(%[\\x1dQ(&\\'-(I#E!0$ЬU.X(-t(\\x1c&z$jED\\x1c(,$;\\x1cP*))\"),\\',(`^a$M5,\\x13\\x18a|(W9Ԯ\\x1e#i$\"\\x9d\\x08ޙ*\\x03!sì.l\\x00S\\x1f\\n$*\\x07!2k7\\'\\x1a$],V(ɪP0%##\\x1fj&\"z\\x0f).((,\\x0f,P#\\x01(G\\x1c./,\\x0bҡ$,\\'j,-˦)\\x08&h\\')&.\\x08.k(.v$̦\\'T\\x10$-Q(:r!(\\x07%O\\x1e\\'!,f-)*A\\x0f)B%t*}\\x0f,\\n.\\x1b-c\\x0c( .})\\x00\\x0c9&7\\x0f֬\\x1b\\x1f,!+\\r,\\x16%\\x1e\\\\\\x1cX\\x16\\x0f\\'ĥ\\x00-G\"\\x1e٥V, *̠!U,|+X\\',&m\\x02\\x01*,ʤQ\\x1d%,l\\x1a\\x15o*\\x12.(w#e\\x14', 'rating': '8'},\n", + " Document {'id': '8', 'payload': None, 'title': 'Inception', 'genre': 'action', 'description': 'A thief who enters dreams to steal secrets faces his toughest mission yet, with reality itself at stake.', 'vector': '**6$\\x18!\"&T+\\x1d١.$\"\\x0e3(%\\x01&*1\\x02**d\\')Щ\\uf805\\x1a-1*%+7էC \\x1c+ܡߡ\\x0f$\\x07**$~\\x1d(+ܫw($)[-\\x17\\x04+\\x0f(G2X-\\x1a+ףsp$%,hIf\\'\\x1cOg!-LA\\x10\\x0b#;\\n\\x03XR&,N-+Jx\\x1f;\\x00ܠ*!?#d(a&iAw\\x15Q.|\\'4*_8,a\\x14/Q8\\x0c*E9\\x1dW)m\\x1b\\x1d,N*&*-K*Wjh2\\'\\x11\\x15g&(\\x10)(\\x1aR\\x16\\x14\\x11),\\x00)9-\\x19*\\x17\\x19#-˨4\\x1aK\\x07ΩݦO&\\x02,\\x1f\\x0b7\\x05x(!\"-g%q\\x03@)\\':\\x07$\\x1d\\x00j-\\x16x\\'r,\\t,7\"\\x1e}*%)/\\r\\n*\\x06q #((\\n(N,o\\x16NE\\x1f߭M%aO-I[\\'y\\x11ħh\\\\\\\\,\\x1c,,\\x00-h)F)\\x03$\\x1b&s\\x1b()@+n%R\")(%`!.\\r)6-\\x11B&.!A((\\x13\\x1c,%J>*N(.ɫ\\x1b\\x08t$S\\x00{2+n*\\x02&W1K,*p\\'g)\\x19\\x18Ț)#-\"~\\'m# X0[&ɪd(\\x0e%6+)D&\\x13,\\x1d(,(\\x7f䧨,ʫ+\\x1eS\\'?\\x18\\x04-,m$M#4(^[\\x1c+\\x05\"\\x15\\x01', 'rating': '9'},\n", + " Document {'id': '9', 'payload': None, 'title': 'The Avengers', 'genre': 'action', 'description': \"Earth's mightiest heroes come together to stop an alien invasion that threatens the entire planet.\", 'vector': '&\\')\\x1b-0¨ȧ,=)\\x1c㞌)O\\x18\\'yu/4(-g+P!c\\x12\\x1dԧt$1\\x03*| m*\\x0fX&Ȭ[\\x1e\\x04\\x1cŬaC#p\\'Ϣ߫,w**\\x14ᠸ\\x1f$˥\\x1ff\\x1b*/\\x0c)\"\\x15<\\x14zc+,9%\\',[]&a\\x16@)4+$`-C+*ӣҪ&: w\\x195F&p \\x7f\\x1d>*0x*B\\x1d`**,)0\\x04\\t*$\\x07)|,x\\x12\\x00G\\x1b\\x1f(\\x1e&l\\x04-)C#_=)\\x0e(\\x1e$i(6\"C4\\x7f+\\x11(\\x03#!,Ξ\\x13J,Q-\"$&?(h+T,S\\x0c,j$d&+XT!f!\\x1b\\'\\x0c\\x1b%\\x18*\\x05+X)\\x1cΰ-%@\\x1f{--04\\t&$(\"X$w)\\x1cy zZ)y$)\\x02K\\x00\\x00˨\\x04\\x1a)\\x00/+)kr*\\x0f,\\x14?,:/\"M&`-(#\\ue840,#((@(\\x160\\x00-e!}C>\"()\\'\\x05+\\',\\x1d,\\x04w),m(a=+\\x1a-*\\'X,(\\x16ק!a,\\x18*+៥ڨs)\\x15?u\\x13$l\\x00~\\x1c,HX)(', 'rating': '8'}]" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "res.docs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Does work with pure redis client.\n", + "client.memory_usage('rvl:37f6b0ea780c4a84a156f35f54a31c7e')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.9" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From c48f7207789b39d2b7f315e8988ba780e772a4e1 Mon Sep 17 00:00:00 2001 From: Robert Shelton Date: Wed, 18 Dec 2024 16:40:10 -0500 Subject: [PATCH 2/5] update example --- .../vector-search/02_float16_support.ipynb | 637 ------------------ .../vector-search/03_float16_support.ipynb | 587 ++++++++++++++++ 2 files changed, 587 insertions(+), 637 deletions(-) delete mode 100644 python-recipes/vector-search/02_float16_support.ipynb create mode 100644 python-recipes/vector-search/03_float16_support.ipynb diff --git a/python-recipes/vector-search/02_float16_support.ipynb b/python-recipes/vector-search/02_float16_support.ipynb deleted file mode 100644 index bddd147..0000000 --- a/python-recipes/vector-search/02_float16_support.ipynb +++ /dev/null @@ -1,637 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'5.0.8'" - ] - }, - "execution_count": 1, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "import redis\n", - "redis.__version__" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "![Redis](https://redis.io/wp-content/uploads/2024/04/Logotype.svg?auto=webp&quality=85,75&width=120)\n", - "# Using smaller vector types\n", - "\n", - "With the [Redis 7.4 release](https://redis.io/blog/announcing-redis-community-edition-and-redis-stack-74/) there is now support for bfloat16 and float16 data types in the vector store. Using this type is exactly the same as using float32 or other data types but will require a conversion if seeking to replace previously stored objects.\n", - "\n", - "This tutorial will walk through repopulating and index as such.\n", - "\n", - "## Packages" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "huggingface/tokenizers: The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...\n", - "To disable this warning, you can either:\n", - "\t- Avoid using `tokenizers` before the fork if possible\n", - "\t- Explicitly set the environment variable TOKENIZERS_PARALLELISM=(true | false)\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "^C\n", - "\u001b[31mERROR: Operation cancelled by user\u001b[0m\u001b[31m\n", - "\u001b[0m\n", - "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m24.0\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.2\u001b[0m\n", - "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n", - "Note: you may need to restart the kernel to use updated packages.\n" - ] - } - ], - "source": [ - "# NBVAL_SKIP\n", - "%pip install -q redis redisvl numpy sentence-transformers" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Install Redis Stack\n", - "\n", - "Later in this tutorial, Redis will be used to store, index, and query vector\n", - "embeddings created from PDF document chunks. **We need to make sure we have a Redis\n", - "instance available.\n", - "\n", - "#### For Colab\n", - "Use the shell script below to download, extract, and install [Redis Stack](https://redis.io/docs/getting-started/install-stack/) directly from the Redis package archive." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# NBVAL_SKIP\n", - "%%sh\n", - "curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg\n", - "echo \"deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main\" | sudo tee /etc/apt/sources.list.d/redis.list\n", - "sudo apt-get update > /dev/null 2>&1\n", - "sudo apt-get install redis-stack-server > /dev/null 2>&1\n", - "redis-stack-server --daemonize yes" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### For Alternative Environments\n", - "There are many ways to get the necessary redis-stack instance running\n", - "1. On cloud, deploy a [FREE instance of Redis in the cloud](https://redis.com/try-free/). Or, if you have your\n", - "own version of Redis Enterprise running, that works too!\n", - "2. Per OS, [see the docs](https://redis.io/docs/latest/operate/oss_and_stack/install/install-stack/)\n", - "3. With docker: `docker run -d --name redis-stack-server -p 6379:6379 redis/redis-stack-server:latest`\n", - "\n", - "##### if running local version make sure to double check it is updated >=7.4\n", - "\n", - "### Define the Redis Connection URL\n", - "\n", - "By default this notebook connects to the local instance of Redis Stack. **If you have your own Redis Enterprise instance** - replace REDIS_PASSWORD, REDIS_HOST and REDIS_PORT values with your own." - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "\n", - "# Replace values below with your own if using Redis Cloud instance\n", - "REDIS_HOST = os.getenv(\"REDIS_HOST\", \"localhost\") # ex: \"redis-18374.c253.us-central1-1.gce.cloud.redislabs.com\"\n", - "REDIS_PORT = os.getenv(\"REDIS_PORT\", \"6379\") # ex: 18374\n", - "REDIS_PASSWORD = os.getenv(\"REDIS_PASSWORD\", \"\") # ex: \"1TNxTEdYRDgIDKM2gDfasupCADXXXX\"\n", - "\n", - "# If SSL is enabled on the endpoint, use rediss:// as the URL prefix\n", - "REDIS_URL = f\"redis://:{REDIS_PASSWORD}@{REDIS_HOST}:{REDIS_PORT}\"" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "# from redis import Redis\n", - "import redis\n", - "\n", - "client = redis.Redis(\n", - " host='redis-11118.c309.us-east-2-1.ec2.redns.redis-cloud.com',\n", - " port=11118,\n", - " password='qt1Zl62JL07F7RTGac40XCiEhksh4xjD')\n", - "# client = Redis.from_url(REDIS_URL)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "client.ping()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Define index and load data\n", - "\n", - "We will be loading a schema of movie information with a 32bit float." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "import json\n", - "\n", - "with open(\"resources/movies.json\", 'r') as file:\n", - " movies = json.load(file)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "07:32:48 redisvl.index.index INFO Index already exists, overwriting.\n" - ] - } - ], - "source": [ - "from redisvl.schema import IndexSchema\n", - "from redisvl.index import SearchIndex\n", - "\n", - "index_name = \"movies32\"\n", - "\n", - "schema = IndexSchema.from_dict({\n", - " \"index\": {\n", - " \"name\": index_name,\n", - " },\n", - " \"fields\": [\n", - " {\n", - " \"name\": \"title\",\n", - " \"type\": \"text\",\n", - " },\n", - " {\n", - " \"name\": \"description\",\n", - " \"type\": \"text\",\n", - " },\n", - " {\n", - " \"name\": \"genre\",\n", - " \"type\": \"tag\",\n", - " \"attrs\": {\n", - " \"sortable\": True\n", - " }\n", - " },\n", - " {\n", - " \"name\": \"rating\",\n", - " \"type\": \"numeric\",\n", - " \"attrs\": {\n", - " \"sortable\": True\n", - " }\n", - " },\n", - " {\n", - " \"name\": \"vector\",\n", - " \"type\": \"vector\",\n", - " \"attrs\": {\n", - " \"dims\": 384,\n", - " \"distance_metric\": \"cosine\",\n", - " \"algorithm\": \"hnsw\",\n", - " \"datatype\": \"float32\"\n", - " }\n", - " }\n", - " ]\n", - "})\n", - "\n", - "\n", - "index = SearchIndex(schema, client)\n", - "index.create(overwrite=True, drop=True)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Embed movie description vectors" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/robert.shelton/.pyenv/versions/3.11.9/lib/python3.11/site-packages/huggingface_hub/file_download.py:1132: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`.\n", - " warnings.warn(\n", - "/Users/robert.shelton/.pyenv/versions/3.11.9/lib/python3.11/site-packages/huggingface_hub/file_download.py:1132: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`.\n", - " warnings.warn(\n" - ] - } - ], - "source": [ - "import numpy as np\n", - "from sentence_transformers import SentenceTransformer\n", - "\n", - "# load model for embedding our movie descriptions\n", - "model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')\n", - "\n", - "def embed_text(model, text):\n", - " return np.array(model.encode(text)).astype(np.float32).tobytes()" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "# Note: convert embedding array to bytes for storage in Redis Hash data type\n", - "movie_data32 = [\n", - " {\n", - " **movie,\n", - " \"vector\": embed_text(model, movie[\"description\"])\n", - " } for movie in movies\n", - "]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Populate the index" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['rvl:37b42d13adaa4a4ea32db5e4d062126b',\n", - " 'rvl:9e3dfc7c67b744bb8199d364c60f8d89',\n", - " 'rvl:8f7758c7763842f78490e3c43aab1148',\n", - " 'rvl:c961854993a04d089da2e026033b80b3',\n", - " 'rvl:7f2699e7dbf3474283d34bf04b465f00',\n", - " 'rvl:cc56f14da1f8431c90a318167ce7e506',\n", - " 'rvl:5c0097099939492f87b2b56890bc7dfe',\n", - " 'rvl:6c215979299c424ebff07a4b85a60f43',\n", - " 'rvl:896cd78dae42483db66019f2b62a70e4',\n", - " 'rvl:b92104d038c04ab3beab80139f75e7d1',\n", - " 'rvl:17b08c1a64b743ecab2e5acaa4a777af',\n", - " 'rvl:d7e8d94d158e4003ad443ec5ce517f53',\n", - " 'rvl:a448ffc20ac8474ab776df5e54ae26a9',\n", - " 'rvl:87e2cd98e776411cb7f552a29a808a2a',\n", - " 'rvl:750ccddcf5604b12b33fb81e78042db0',\n", - " 'rvl:403fcaf607b04e5a9b7561a86082cb26',\n", - " 'rvl:12e4333184554daca7cbbf44e77ccb18',\n", - " 'rvl:5be2ed277c1c4f3b8afb929446afda9e',\n", - " 'rvl:6ccdd8c9eb1f433fa92c85f16d4351ff',\n", - " 'rvl:7ba0ee30d58f45e7bc1d5d21fbe9a45d']" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "keys = index.load(movie_data32)\n", - "keys" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], - "source": [ - "client.memory_usage('rvl:37f6b0ea780c4a84a156f35f54a31c7e')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Now let's convert to fp16\n", - "\n", - "This is as simple as you think it is using numpy." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [], - "source": [ - "movie_data16 = []\n", - "for movie in movie_data32:\n", - " vect16 = np.frombuffer(movie[\"vector\"], dtype=np.float32).astype(np.float16)\n", - " movie[\"vector\"] = vect16.tobytes()\n", - " movie_data16.append(movie)" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'title': 'Explosive Pursuit',\n", - " 'genre': 'action',\n", - " 'rating': 7,\n", - " 'description': 'A daring cop chases a notorious criminal across the city in a high-stakes game of cat and mouse.',\n", - " 'vector': b'\\xe3+S\\x18\\xbd\\x1d\\xf6\\xabs\\x9eQ*\\xfd)\\xac$8\\xb0{.\\x80+o\\xa8H\\xaa3&\\x0f+\\xb2\\xa0\\x9f \\xe5(O$n!\\xfe\\xa4\\x18\\xae\\x92*\\xbb\\xa7\\xba\\xb0)\\x88\\xfc%\\x17\\x93E\\xadg\\xa7+)\\x97\\x9b:*),\\x12\\xa5\\x83\\xaeY\\xaa\\xa7\\xa4G*1\"a\\'o\\xac\\xc3$\\x1d-\\x9b\\xa9\\xee\\xad\\xb9\\x1f\\xd8+f,0\\xae\\x82\\xac\\xe9\\x1dg\\xa8J\\xa6\\xe0\\xa5\\xa9\\x9bT&T*U)\\xaa\\xaa\\xb0\\xa4\\xc8(`\"N(d-\\xc7\\xad\\xe6\\xac\\xc4(3)\\xc2\\'H$\\x94\\x9f\\xda\\xaau\\x9f\\n\\xaa\\xcb\\xa8\\x93\\x9f\\xc6\\x1bz\"b\\xa1u-h\\xa1p\\xad\\xd7(n.\\x81)\\xf0\\xa4Z*\\x06)P\\xaa\\xf3\\x9c\\xbc\\x17\\xe8(\\xf6&\\xb3\\x98\\x83\\x9b\\xe7!\\x1d\\x85\\x9a#2!\\xc1 o\\xa9\\xc7$u*)-\\xf0&\\x9a p\\x96\\xe5\\xa6*(\\xad\\'\\x97\\xa2m\\xa1\\xe7\\nb/\\xb8*\\xb2\\xa6\\x99*\\xf7\\xaa\\x8d$\\x9f \\xce\\x9b|\\xa9\\x80#E\\x9c\\xef$\\xb0-\\x00\\x808\\x9d0\\xab[\\x9a\\x81\\x9c\\xcc\\x9d\\xce\\x9d[+h%C\\xadc.\\x07\\xb1z\\xa9\\xbb\\xa7\\xb5+\\x88#\\xe7\\xa8X$3\\xa54$\\xcc(%\\xa7\\xf3\\xa2s\\xa8\\x1e\\xa7\\xaa\\x1a\\xe2\\xab`\\xacT\\xa9\\xa4/\\x86\\x18q\\xa8\\xa7-\\xa9\\xa8\\x1c,\\xd1!\\x0f%h\\xacH\\xab\\xe8&\\xb4.\\xe5\\xac\\x0c\\xa9)\\x8e\\x9e\\xa4\\xf6\\xa91\\xaa\\xa2\\xb0D\\xa9J\\xac\\xa5&\\x19.x\\xaa\\x84\\xa3f\\xa5-\\xab\\x9c\\x1b\\x0b\\x1e\\x18\\xaa\\xf1\\x17\\xa7/Q!\\xe0(\\xb8\\xaao(7(\\xd4\\xad\\xb5&\\xcf\\x1ez).,\\x10){\\'\\x1f+B\\xb0\\xd9)\\xbb\\x1a\\x15#\\xbd%\\xdc\\xa9\\x8c\\xa4\\xe0\\xa9\\x19%*\\xa1\\xff\\x9d\\x94(\\xa9,\\xec\\xa7\\x90\\xae$\\x1c\\xa8+L#\\x95\\xaap\\xab\\x9e)7*\\x00\\x00\\xd2%}\\xaa8\\x1e(\\xa8\\x94\\xac\\'*\\xdf\\xa1\\xa2\\xa7\\xbc\\xack\\xa8\\xac\\xafA)6.\\xd7(\\xc5/v\\xa7\\xc1\\x98\\xdc!J\\xa8\\xb8(\\xf5(Z\\xaeh\\xack\\x9f\\xcb\\xa0\\x98\\xa0\\x1c,$\\xab\\x8e\\x9e\\xcb\\xa2\\x0c+\\xee\\xa7\\x1d\\x9c\\xca\\xa8\\xe8\\xaa\\xd7+\\xe2,K\\xad\\xcb\\xa1w\\xa2\\xc0\\xab\\x04-\\xb5$\\xc4\\x91\\xee\\xa9D!\\xa7\\x9d^\\xa8\\xa8\\xac\\xa6*\\x8c&:\\xa9@\"\\xc0%\\xeb\\xab\\x0c(\\xde\\xaa\\x1f {\\xa8<\\xa7A&\\xe0,7\\xad+/y\"\\x98)\\xb2\\xa9\\x97\\xa7;%\\x16\\xb0\\x93\\xa9T,N\\xa8n\\xa6o\\x9d\\xf8\\xa6)*\\xe8-i+s,%-U\\x9ej\\xa0\\xe2$s\\xacY+\\xf8\\x1d\\xf9\\'\\x92$b\\x1c\\x1d-\\xb1#\\x84\\x9f?\\xa0\\xed\\xa5\\x00\\x80\\x9c\\xaeW+?\\xad)\\'\\x81+\\xff,B\\xab\\xa5\\xaf?\\xa0W#\\xbc+\\x0f\\'\\xf5(\"&R #\\xa3h,4\\xa5i\\x96|.k\\xa9s+\\xf9\\xac\\xfc*\\x19!m\\x1b\\x04\\xb0\\\\\\xa4;*U.\\x8e\\xa3\\xd7\\xa9\\xed\"\\x8b\\x1es-\\x19\\xa8J,\\x9a\\xab\\x11+N\\x98@\\'&\\xa7\\x1b)\\\\\\xab\\x0b w\\xaa\\x88\\xa5P\\xaa\\xf8+\\xd7\\xaa\\x89\\x9f\\xc2)\\xa2\\xa2\\t$m*/ \\xe2\\xab\\xbd#?\\xad\\x03\\xa99(\\xa1\\xa0L\\'\\xb9,'}" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "movie_data16[0]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Create new index" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "ename": "ValidationError", - "evalue": "1 validation error for IndexSchema\n__root__ -> attrs -> datatype\n value is not a valid enumeration member; permitted: 'FLOAT32', 'FLOAT64' (type=type_error.enum; enum_values=[, ])", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mValidationError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[12], line 6\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mredisvl\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mindex\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m SearchIndex\n\u001b[1;32m 4\u001b[0m index_name \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmovies16\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m----> 6\u001b[0m schema \u001b[38;5;241m=\u001b[39m \u001b[43mIndexSchema\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfrom_dict\u001b[49m\u001b[43m(\u001b[49m\u001b[43m{\u001b[49m\n\u001b[1;32m 7\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mindex\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43m{\u001b[49m\n\u001b[1;32m 8\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mname\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mindex_name\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 9\u001b[0m \u001b[43m \u001b[49m\u001b[43m}\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 10\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mfields\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43m[\u001b[49m\n\u001b[1;32m 11\u001b[0m \u001b[43m \u001b[49m\u001b[43m{\u001b[49m\n\u001b[1;32m 12\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mname\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtitle\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 13\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtype\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtext\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 14\u001b[0m \u001b[43m \u001b[49m\u001b[43m}\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 15\u001b[0m \u001b[43m \u001b[49m\u001b[43m{\u001b[49m\n\u001b[1;32m 16\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mname\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mdescription\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 17\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtype\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtext\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 18\u001b[0m \u001b[43m \u001b[49m\u001b[43m}\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 19\u001b[0m \u001b[43m \u001b[49m\u001b[43m{\u001b[49m\n\u001b[1;32m 20\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mname\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mgenre\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 21\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtype\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtag\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 22\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mattrs\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43m{\u001b[49m\n\u001b[1;32m 23\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43msortable\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\n\u001b[1;32m 24\u001b[0m \u001b[43m \u001b[49m\u001b[43m}\u001b[49m\n\u001b[1;32m 25\u001b[0m \u001b[43m \u001b[49m\u001b[43m}\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 26\u001b[0m \u001b[43m \u001b[49m\u001b[43m{\u001b[49m\n\u001b[1;32m 27\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mname\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mrating\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 28\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtype\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mnumeric\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 29\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mattrs\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43m{\u001b[49m\n\u001b[1;32m 30\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43msortable\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\n\u001b[1;32m 31\u001b[0m \u001b[43m \u001b[49m\u001b[43m}\u001b[49m\n\u001b[1;32m 32\u001b[0m \u001b[43m \u001b[49m\u001b[43m}\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 33\u001b[0m \u001b[43m \u001b[49m\u001b[43m{\u001b[49m\n\u001b[1;32m 34\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mname\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mvector\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 35\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtype\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mvector\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 36\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mattrs\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43m{\u001b[49m\n\u001b[1;32m 37\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mdims\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m384\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 38\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mdistance_metric\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mcosine\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 39\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43malgorithm\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mhnsw\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 40\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mdatatype\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mfloat16\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m 41\u001b[0m \u001b[43m \u001b[49m\u001b[43m}\u001b[49m\n\u001b[1;32m 42\u001b[0m \u001b[43m \u001b[49m\u001b[43m}\u001b[49m\n\u001b[1;32m 43\u001b[0m \u001b[43m \u001b[49m\u001b[43m]\u001b[49m\n\u001b[1;32m 44\u001b[0m \u001b[43m}\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 47\u001b[0m index \u001b[38;5;241m=\u001b[39m SearchIndex(schema, client)\n\u001b[1;32m 48\u001b[0m index\u001b[38;5;241m.\u001b[39mcreate(overwrite\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m, drop\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)\n", - "File \u001b[0;32m~/.pyenv/versions/3.11.9/lib/python3.11/site-packages/redisvl/schema/schema.py:263\u001b[0m, in \u001b[0;36mIndexSchema.from_dict\u001b[0;34m(cls, data)\u001b[0m\n\u001b[1;32m 227\u001b[0m \u001b[38;5;129m@classmethod\u001b[39m\n\u001b[1;32m 228\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mfrom_dict\u001b[39m(\u001b[38;5;28mcls\u001b[39m, data: Dict[\u001b[38;5;28mstr\u001b[39m, Any]) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mIndexSchema\u001b[39m\u001b[38;5;124m\"\u001b[39m:\n\u001b[1;32m 229\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Create an IndexSchema from a dictionary.\u001b[39;00m\n\u001b[1;32m 230\u001b[0m \n\u001b[1;32m 231\u001b[0m \u001b[38;5;124;03m Args:\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 261\u001b[0m \u001b[38;5;124;03m })\u001b[39;00m\n\u001b[1;32m 262\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m--> 263\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mcls\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mdata\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/.pyenv/versions/3.11.9/lib/python3.11/site-packages/pydantic/v1/main.py:341\u001b[0m, in \u001b[0;36mBaseModel.__init__\u001b[0;34m(__pydantic_self__, **data)\u001b[0m\n\u001b[1;32m 339\u001b[0m values, fields_set, validation_error \u001b[38;5;241m=\u001b[39m validate_model(__pydantic_self__\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__class__\u001b[39m, data)\n\u001b[1;32m 340\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m validation_error:\n\u001b[0;32m--> 341\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m validation_error\n\u001b[1;32m 342\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 343\u001b[0m object_setattr(__pydantic_self__, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m__dict__\u001b[39m\u001b[38;5;124m'\u001b[39m, values)\n", - "\u001b[0;31mValidationError\u001b[0m: 1 validation error for IndexSchema\n__root__ -> attrs -> datatype\n value is not a valid enumeration member; permitted: 'FLOAT32', 'FLOAT64' (type=type_error.enum; enum_values=[, ])" - ] - } - ], - "source": [ - "from redisvl.schema import IndexSchema\n", - "from redisvl.index import SearchIndex\n", - "\n", - "index_name = \"movies16\"\n", - "\n", - "# this won't work till we merge Justin's stuff\n", - "schema = IndexSchema.from_dict({\n", - " \"index\": {\n", - " \"name\": index_name,\n", - " },\n", - " \"fields\": [\n", - " {\n", - " \"name\": \"title\",\n", - " \"type\": \"text\",\n", - " },\n", - " {\n", - " \"name\": \"description\",\n", - " \"type\": \"text\",\n", - " },\n", - " {\n", - " \"name\": \"genre\",\n", - " \"type\": \"tag\",\n", - " \"attrs\": {\n", - " \"sortable\": True\n", - " }\n", - " },\n", - " {\n", - " \"name\": \"rating\",\n", - " \"type\": \"numeric\",\n", - " \"attrs\": {\n", - " \"sortable\": True\n", - " }\n", - " },\n", - " {\n", - " \"name\": \"vector\",\n", - " \"type\": \"vector\",\n", - " \"attrs\": {\n", - " \"dims\": 384,\n", - " \"distance_metric\": \"cosine\",\n", - " \"algorithm\": \"hnsw\",\n", - " \"datatype\": \"float16\"\n", - " }\n", - " }\n", - " ]\n", - "})\n", - "\n", - "\n", - "index = SearchIndex(schema, client)\n", - "index.create(overwrite=True, drop=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [], - "source": [ - "from redis.commands.search.field import VectorField, TagField, NumericField, TextField\n", - "from redis.commands.search.indexDefinition import IndexDefinition, IndexType\n", - "\n", - "index_name = \"movies\"\n", - "\n", - "schema = (\n", - " VectorField(\n", - " \"vector\",\n", - " \"HNSW\",\n", - " {\n", - " \"TYPE\": \"FLOAT16\",\n", - " \"DIM\": 384,\n", - " \"DISTANCE_METRIC\": \"COSINE\"\n", - " }\n", - " ),\n", - " NumericField(\"rating\"),\n", - " TagField(\"genre\"),\n", - " TextField(\"title\"),\n", - " TextField(\"description\")\n", - ")\n", - "\n", - "try:\n", - " client.ft(index_name).info()\n", - " print(\"Index exists!\")\n", - "except:\n", - " # index Definition\n", - " definition = IndexDefinition(index_type=IndexType.HASH)\n", - "\n", - " # create Index\n", - " client.ft(index_name).create_index(fields=schema, definition=definition)" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [], - "source": [ - "def load_docs(client: redis.Redis, data: list[dict]):\n", - " for i, d in enumerate(data):\n", - " client.hset(\n", - " i,\n", - " mapping = d\n", - " )\n", - "\n", - "def print_results(res):\n", - " docs = [(doc.title, doc.genre, doc.rating) for doc in res.docs]\n", - " print(f\"Top {len(docs)} movies: \", docs)" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [], - "source": [ - "load_docs(client, movie_data16)" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Result{20 total, docs: [Document {'id': '0', 'payload': None, 'title': 'Explosive Pursuit', 'genre': 'action', 'description': 'A daring cop chases a notorious criminal across the city in a high-stakes game of cat and mouse.', 'vector': '+S\\x18\\x1dsQ*)$8{.+oH3&\\x0f+ (O$n!\\x18*)%\\x17Eg+):*),\\x12YG*1\"a\\'o$\\x1d-\\ueb79\\x1f+f,0\\x1dgJ३T&T*U)(`\"N(d-ǭ(3)\\'H$ڪu\\n˨\\x1bz\"bu-hp(n.)Z*\\x06)P\\x17(&!\\x1d#2! o$u*)-& p*(\\'m\\nb/**$ Λ|#E$-\\x0080[̝Ν[+h%Cc.\\x07z+#X$34$(%s\\x1e\\x1a`T/\\x18q-\\x1c,!\\x0f%hH&.\\x0c)1DJ&\\x19.xf-\\x1b\\x0b\\x1e\\x18\\x17/Q!(o(7(ԭ&\\x1ez).,\\x10){\\'\\x1f+B)\\x1a\\x15#%ܩ\\x19%*(,짐$\\x1c+L#p)7*\\x00\\x00%}8\\x1e(\\'*ߡkA)6.(/v!J((Zhkˠ\\x1c,$ˢ\\x0c+\\x1dʨ+,Kˡw\\x04-$đD!^*&:@\"%\\x0c(ު\\x1f {\\x07(.\\x1c@.\\x1e[)߬,\"5(\\x1f([\\x00|7\\x1e+19A-\\x16%\\x1f$\\x08,KX\\x1d*.m-ۢ寋\\x1f)\\x17v(*\"3%N)&\\x1f\\x1f\\x02\\x15\\x04\\x16,\\x9ey!Z+\\x12|\\x08$Uz%\\x1cRh\\x0c\\x18(#N\\x1dGJdÕX\\x0c\\x19蜗./\\x1b\"̘%)b+**.Ϫ\\x00 @,_-\\x042y+.1\\x1fS{)d\\x00\\x00o\\x1eɪ:\\x7f,\\x08w\"] \\x1c.W\\'!\\x00)Ѧ\\x06\\'\\x04-\\x1b\\x17.L %\\x1c,6$+M\\x1du\\x1f\\'e0#*(z)V,$\\x02ܬ\"&p%\\r2\\x1f-D\\'t*9\\x03ά%˩%$\\x1aW)%,<\\x15,!%\\x1f!k\\x1e&\\x16*)\\x17\\x1e((u*(>\\x03[\\x1cc,%\\x003p(w*\\x16\\x1f4 =)+]\\x14\\x18\\x1a#\\x1e,G\\x1f!\\'ڦ\\',\\x1c\\x1f)\\t$j/)N)\\x16(\\x0co+t? \\x06.-ר+\\x18,\\x18ԫf*O)\\n kũ`*)\\x0f\\'m\\\\%B#\\x17)', 'rating': '8'}, Document {'id': '2', 'payload': None, 'title': 'Fast & Furious 9', 'genre': 'action', 'description': 'Dom and his crew face off against a high-tech enemy with advanced weapons and technology.', 'vector': '=\\x11-A\\x1d*+\\x01-g4);(m+\\x1c\\rT,\\x1e+b#\\x1bء(\\x18\\x00.q-uڥL(֦\\x08>}-\\x1d*O¬P \\x18\\x05)J\\x1a,\\x1b*!)\\x19&\\x14R,A#Wo&ʡA+\\r+),-\\x1dU#ߤ&&\\x1fᗬ/۩?*3˕~+Ȩ._)s&\\x02.\\x1c\\x11-,$%<+)\\x04\\'(,d$1g3*![%8\\t5)V1(LӨ|.-*\\x00\\x19\"Z+(* c-\\x19ǩ$A\\x1d\\x1c*ޣ\\t\\x16M\\'#E%,l\\x155\\x1f)-\\x00\\x15,\\x10*1-(ͥȫj\\x11I$\\x13\\'\"+\\x19%˨#\\'\\'\\'\\u2438-(**,*˦[t)r\\x02)H*U(먤%p\"$#$\\x1b$\\x0eb\\'AC)?\\x1aD\\x14dާ\\x00\\x008b& u*z\\x1f,+],)Bp5r,\\x0c\\x12,S\\x1c(1y\\',)Z*p(\\x19+\\x07$e 0*ө_\\x0b,Ĥ~7.vQ\\x1c\\x15&~) c,G,\\x1b!;*\\x07\\x1d\\x10(J-\\x1b,/.ά*ik) \\x1cp*k(\\x1e¨-)c/ɝ\\x12\\\\w{\\x1f\\x1c9\\x00dG\\x01\\x1f&۩h,A\\x1d$ -h\\'R+,\\x0bcԮ\\x08\\x1d).(o%-z&,-; \\x1c0\\x13*Μ,ҭ*H\\'v,K-\\x90\\x02\\x13\\x1d\\x04)$-Ir$B 9\\x15,R(', 'rating': '6'}, Document {'id': '3', 'payload': None, 'title': 'Black Widow', 'genre': 'action', 'description': 'Natasha Romanoff confronts her dark past and family ties as she battles a new enemy.', 'vector': '/~\\x17+%\\x04-Z(Δ\\x1f?\\x1c\\x16$6:B\\x14$\\x1c\\r\\x1ff\\x0b#)\\x06\\'(6\\x1c&\\x13),\"&$*-y)&)E*R\\x00u\\x16$.\\x1d\\x07\\x14V\\x1dXn)-.)\\x1d\\'\\'*]J\\x13)\\'%{,Y\\x07*+D˪\\x11..(%\\x15))\"M!(\\x17\\n!R+\\x02E\\x1f ^,\\'&Ց$\\x10**\\x0f1(ڨ)rڬ)+&\\x17.\\x01 /\\x18oK,J)[*\\x06%T\\x1f8\\x00N#%K\\x16/(!)r(}\\x1eV,x`)d*j(#/z\\x1d/0\\x13?ӧ\\n(6(}$*%\\'-$d*\\'(\\x06\\x14\\x1e\\x13`(JY4#v,4T!<\\x02\\x00*$\\x17-\\'i5*\\x14+\\x18\\x19ҥi&($.\\x1c t\\x1a!)\\x0f,6۬7\\'A*\\x04\\x1f\\x08(\\x02\\x05)|&\\x00-k\\x7f&,⡡X.P!\\x0b)!(2(#Ѫ.\\x1e\\x94\\x10\\x1a\\x06`,j0}\\x15oG\\x06\\x1b\\'*0*ˮ\\'$8\\x0b-?-m/u)0\\x0eXt*~,ί)\\x1f,/D\\x10%v\\x00zl\\x1f٩j-̦2\\x1b,]$\\x0b\\'$)F\\',\\x13/&}.E(gK\\x14L\\x00硇R\\'Ȭժ+\\x1bb\\x1a\\x1d*\\x05\"j)#Ϊ1.k-7we\\x13\\x05\\'g\\x15rΥ\\t,)%!Ҩy-%f\\x1fwg*P,hRw\"*+1<\\x18\\x1c\\x1a)m(8)\"\\x0c*%,h*U', 'rating': '7'}, Document {'id': '4', 'payload': None, 'title': 'John Wick', 'genre': 'action', 'description': 'A retired hitman seeks vengeance against those who wronged him, leaving a trail of destruction in his wake.', 'vector': '\\x9b).\\x19$\\x1b\\r#Mդk\\'\\x03H(p\\x1f%2$.l$@:-/\\x11QSѥ\\x03*%թţ\\x1cޭO$*H#%%h$ʩ\\x0f!C+\\x00*fa((h(kx-y\\x1ch*ĢQ()d%\\\\,U(j,)E$\\x0e|$%,Q!^-* #*K+)$%1\\x10,˧*k.؟l5#()$ѯ\\x15,\\x0eϘd(\\x1c,窺;,4(!k\\x1d\\x19,\\x1d\\x00(&& \\x00y,#\\n\\'w%\\x16&a)&*y\\x11/$\"?#,ެP\\x08.ǥ(\\x17g#(5xi/,U*!#a(u(\\x0c\\x16\\x19T$.h1!0%%w\\x01,[\">N\\'A(4\\x19+\\x03Y\\x1f.\"\\x1e\\n:\\x1d-<\\x1e)\\x00P)D*ڦ\\x15%&ʨե&\\'\\x05\\x01\\t&+$$p,=\\x00\\x18#\\')\\x03,\\x1e,,t4>1/\\x1f#\\x10QM\"=-\\x0b̟],2\\x0b#)H-9.& V#h\\x1e\\'$\\x02$+0\\x16+.\\x06)\\'\\'-\\'d*E\\x1eŬ \\x061\\x14R)ƩVW*\\x10XI&ͫ\\x04\"#\\'ҭ\\x17,\\x0f\\x1fB)#\\'!ӟ\\x00\\x04ꕔ%\\x12 +!]m*\\x19%o--s\\x1e$(Nάܪ\\x1cq\"(,N*&\\x1eB) \\x0e(y%p)+\\x10?A,(\\'3ǮW $wt)+\"\\x0c)t)yY(!Ƥ0\\x0536\"', 'rating': '8'}, Document {'id': '6', 'payload': None, 'title': 'The Dark Knight', 'genre': 'action', 'description': 'Batman faces off against the Joker, a criminal mastermind who threatens to plunge Gotham into chaos.', 'vector': '\\n/)j &*,\\'l$rR(\\x1d;ѥZ%, (*]-|\\x1f\\x03k+v(+$\\x1d)֭(6#բ0E+0() =&$9Y+*}\\x12+m(\\x1c(\\x11$I!V.()\"\\'l)J),\\x12*O Р,V\\'X$Ϥ&\\'\\x1a,\\x11\\')\\'N*ʠ1\\'\\x1c-::DJ)%\\'}(4\\x1fg\\'+S\\x08\\\\\\x07-\\x1f\\x10 !,*L)0**d),\\n--G!\\x15O)[Ȫ\\x00u\\x05\\x11T,fS%8)0!ps0e\\x07,\\x0c\\'7\\x0e\\x19g\\x08 g%\\x04\"(l*#R-c_)G)*\\x1adĭM\\x15̨߬#y ($쬮#9~)S\\x7f\\x0b#*\\x1fr\\x1fǡ5T\"+\\x19\"4\\'\\x17),\\x7fQ*d)\\t/T\\n\\x1c#ҭ¬\\r%\\x19s)릶(j*\\x00&@q9#\\x1dʬ*Y\\x1f8,(,*+\\x14)H&Eȡ\\x01\\n\\x17*#!\\t*l&(&((0gJ+\\x02)x\\x1c*\\x0f+Z.<(\\r(a$\\n( r`\\x1d}\\x11]1\\')N*\\x14%u+d(/\\x18\\x1fz\\x07ު\\r)!דɧ$+?(\\x10.\\x1f\\x12*\\x07*\\x05+%\\x00T˪]!\\x03$s+;Il*x%t% ,Z\\x06\\x0f=\\x18ȮC >\\',*ߣ3,\\x1a/*R$(t,ǩ\\\\$*~(;+2K& \\x1c\"uT\\x1d\\\\\\x11)Pfz$M)\\x15,\\x0b*b\\x1e', 'rating': '9'}, Document {'id': '7', 'payload': None, 'title': 'Gladiator', 'genre': 'action', 'description': 'A betrayed Roman general seeks revenge against the corrupt emperor who murdered his family.', 'vector': '.+\\x93;m^)\\x7f*\\x19\\x1a*3#\\x01\\x02.~$\\x02+$\\x1f|)e+X\\x04\\x04(C7,p\\x05\\x05M|+%.\\'*.50\\'~+(*$\\'t&\\x1a\\x11.\\x01\\x12\\'Ц+ (,\\x13\\'\\x1aWX\\';? \\x1c/Z+x\\x1d\\x1c\\x1a)\\x0f%jqT\\x14s*7\\x1e[*Fo,\\x0c0*hW*̠]-++h(o\\x1ebh)*\\x16\\x003\\x1clb!)*\\x0b\\x1dy.\\x1f@+,vV.,\\x197&(%[\\x1dQ(&\\'-(I#E!0$ЬU.X(-t(\\x1c&z$jED\\x1c(,$;\\x1cP*))\"),\\',(`^a$M5,\\x13\\x18a|(W9Ԯ\\x1e#i$\"\\x9d\\x08ޙ*\\x03!sì.l\\x00S\\x1f\\n$*\\x07!2k7\\'\\x1a$],V(ɪP0%##\\x1fj&\"z\\x0f).((,\\x0f,P#\\x01(G\\x1c./,\\x0bҡ$,\\'j,-˦)\\x08&h\\')&.\\x08.k(.v$̦\\'T\\x10$-Q(:r!(\\x07%O\\x1e\\'!,f-)*A\\x0f)B%t*}\\x0f,\\n.\\x1b-c\\x0c( .})\\x00\\x0c9&7\\x0f֬\\x1b\\x1f,!+\\r,\\x16%\\x1e\\\\\\x1cX\\x16\\x0f\\'ĥ\\x00-G\"\\x1e٥V, *̠!U,|+X\\',&m\\x02\\x01*,ʤQ\\x1d%,l\\x1a\\x15o*\\x12.(w#e\\x14', 'rating': '8'}, Document {'id': '8', 'payload': None, 'title': 'Inception', 'genre': 'action', 'description': 'A thief who enters dreams to steal secrets faces his toughest mission yet, with reality itself at stake.', 'vector': '**6$\\x18!\"&T+\\x1d١.$\"\\x0e3(%\\x01&*1\\x02**d\\')Щ\\uf805\\x1a-1*%+7էC \\x1c+ܡߡ\\x0f$\\x07**$~\\x1d(+ܫw($)[-\\x17\\x04+\\x0f(G2X-\\x1a+ףsp$%,hIf\\'\\x1cOg!-LA\\x10\\x0b#;\\n\\x03XR&,N-+Jx\\x1f;\\x00ܠ*!?#d(a&iAw\\x15Q.|\\'4*_8,a\\x14/Q8\\x0c*E9\\x1dW)m\\x1b\\x1d,N*&*-K*Wjh2\\'\\x11\\x15g&(\\x10)(\\x1aR\\x16\\x14\\x11),\\x00)9-\\x19*\\x17\\x19#-˨4\\x1aK\\x07ΩݦO&\\x02,\\x1f\\x0b7\\x05x(!\"-g%q\\x03@)\\':\\x07$\\x1d\\x00j-\\x16x\\'r,\\t,7\"\\x1e}*%)/\\r\\n*\\x06q #((\\n(N,o\\x16NE\\x1f߭M%aO-I[\\'y\\x11ħh\\\\\\\\,\\x1c,,\\x00-h)F)\\x03$\\x1b&s\\x1b()@+n%R\")(%`!.\\r)6-\\x11B&.!A((\\x13\\x1c,%J>*N(.ɫ\\x1b\\x08t$S\\x00{2+n*\\x02&W1K,*p\\'g)\\x19\\x18Ț)#-\"~\\'m# X0[&ɪd(\\x0e%6+)D&\\x13,\\x1d(,(\\x7f䧨,ʫ+\\x1eS\\'?\\x18\\x04-,m$M#4(^[\\x1c+\\x05\"\\x15\\x01', 'rating': '9'}, Document {'id': '9', 'payload': None, 'title': 'The Avengers', 'genre': 'action', 'description': \"Earth's mightiest heroes come together to stop an alien invasion that threatens the entire planet.\", 'vector': '&\\')\\x1b-0¨ȧ,=)\\x1c㞌)O\\x18\\'yu/4(-g+P!c\\x12\\x1dԧt$1\\x03*| m*\\x0fX&Ȭ[\\x1e\\x04\\x1cŬaC#p\\'Ϣ߫,w**\\x14ᠸ\\x1f$˥\\x1ff\\x1b*/\\x0c)\"\\x15<\\x14zc+,9%\\',[]&a\\x16@)4+$`-C+*ӣҪ&: w\\x195F&p \\x7f\\x1d>*0x*B\\x1d`**,)0\\x04\\t*$\\x07)|,x\\x12\\x00G\\x1b\\x1f(\\x1e&l\\x04-)C#_=)\\x0e(\\x1e$i(6\"C4\\x7f+\\x11(\\x03#!,Ξ\\x13J,Q-\"$&?(h+T,S\\x0c,j$d&+XT!f!\\x1b\\'\\x0c\\x1b%\\x18*\\x05+X)\\x1cΰ-%@\\x1f{--04\\t&$(\"X$w)\\x1cy zZ)y$)\\x02K\\x00\\x00˨\\x04\\x1a)\\x00/+)kr*\\x0f,\\x14?,:/\"M&`-(#\\ue840,#((@(\\x160\\x00-e!}C>\"()\\'\\x05+\\',\\x1d,\\x04w),m(a=+\\x1a-*\\'X,(\\x16ק!a,\\x18*+៥ڨs)\\x15?u\\x13$l\\x00~\\x1c,HX)(', 'rating': '8'}]}" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "res = client.ft(index_name).search(\"*\")\n", - "res" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Document {'id': '0', 'payload': None, 'title': 'Explosive Pursuit', 'genre': 'action', 'description': 'A daring cop chases a notorious criminal across the city in a high-stakes game of cat and mouse.', 'vector': '+S\\x18\\x1dsQ*)$8{.+oH3&\\x0f+ (O$n!\\x18*)%\\x17Eg+):*),\\x12YG*1\"a\\'o$\\x1d-\\ueb79\\x1f+f,0\\x1dgJ३T&T*U)(`\"N(d-ǭ(3)\\'H$ڪu\\n˨\\x1bz\"bu-hp(n.)Z*\\x06)P\\x17(&!\\x1d#2! o$u*)-& p*(\\'m\\nb/**$ Λ|#E$-\\x0080[̝Ν[+h%Cc.\\x07z+#X$34$(%s\\x1e\\x1a`T/\\x18q-\\x1c,!\\x0f%hH&.\\x0c)1DJ&\\x19.xf-\\x1b\\x0b\\x1e\\x18\\x17/Q!(o(7(ԭ&\\x1ez).,\\x10){\\'\\x1f+B)\\x1a\\x15#%ܩ\\x19%*(,짐$\\x1c+L#p)7*\\x00\\x00%}8\\x1e(\\'*ߡkA)6.(/v!J((Zhkˠ\\x1c,$ˢ\\x0c+\\x1dʨ+,Kˡw\\x04-$đD!^*&:@\"%\\x0c(ު\\x1f {\\x07(.\\x1c@.\\x1e[)߬,\"5(\\x1f([\\x00|7\\x1e+19A-\\x16%\\x1f$\\x08,KX\\x1d*.m-ۢ寋\\x1f)\\x17v(*\"3%N)&\\x1f\\x1f\\x02\\x15\\x04\\x16,\\x9ey!Z+\\x12|\\x08$Uz%\\x1cRh\\x0c\\x18(#N\\x1dGJdÕX\\x0c\\x19蜗./\\x1b\"̘%)b+**.Ϫ\\x00 @,_-\\x042y+.1\\x1fS{)d\\x00\\x00o\\x1eɪ:\\x7f,\\x08w\"] \\x1c.W\\'!\\x00)Ѧ\\x06\\'\\x04-\\x1b\\x17.L %\\x1c,6$+M\\x1du\\x1f\\'e0#*(z)V,$\\x02ܬ\"&p%\\r2\\x1f-D\\'t*9\\x03ά%˩%$\\x1aW)%,<\\x15,!%\\x1f!k\\x1e&\\x16*)\\x17\\x1e((u*(>\\x03[\\x1cc,%\\x003p(w*\\x16\\x1f4 =)+]\\x14\\x18\\x1a#\\x1e,G\\x1f!\\'ڦ\\',\\x1c\\x1f)\\t$j/)N)\\x16(\\x0co+t? \\x06.-ר+\\x18,\\x18ԫf*O)\\n kũ`*)\\x0f\\'m\\\\%B#\\x17)', 'rating': '8'},\n", - " Document {'id': '2', 'payload': None, 'title': 'Fast & Furious 9', 'genre': 'action', 'description': 'Dom and his crew face off against a high-tech enemy with advanced weapons and technology.', 'vector': '=\\x11-A\\x1d*+\\x01-g4);(m+\\x1c\\rT,\\x1e+b#\\x1bء(\\x18\\x00.q-uڥL(֦\\x08>}-\\x1d*O¬P \\x18\\x05)J\\x1a,\\x1b*!)\\x19&\\x14R,A#Wo&ʡA+\\r+),-\\x1dU#ߤ&&\\x1fᗬ/۩?*3˕~+Ȩ._)s&\\x02.\\x1c\\x11-,$%<+)\\x04\\'(,d$1g3*![%8\\t5)V1(LӨ|.-*\\x00\\x19\"Z+(* c-\\x19ǩ$A\\x1d\\x1c*ޣ\\t\\x16M\\'#E%,l\\x155\\x1f)-\\x00\\x15,\\x10*1-(ͥȫj\\x11I$\\x13\\'\"+\\x19%˨#\\'\\'\\'\\u2438-(**,*˦[t)r\\x02)H*U(먤%p\"$#$\\x1b$\\x0eb\\'AC)?\\x1aD\\x14dާ\\x00\\x008b& u*z\\x1f,+],)Bp5r,\\x0c\\x12,S\\x1c(1y\\',)Z*p(\\x19+\\x07$e 0*ө_\\x0b,Ĥ~7.vQ\\x1c\\x15&~) c,G,\\x1b!;*\\x07\\x1d\\x10(J-\\x1b,/.ά*ik) \\x1cp*k(\\x1e¨-)c/ɝ\\x12\\\\w{\\x1f\\x1c9\\x00dG\\x01\\x1f&۩h,A\\x1d$ -h\\'R+,\\x0bcԮ\\x08\\x1d).(o%-z&,-; \\x1c0\\x13*Μ,ҭ*H\\'v,K-\\x90\\x02\\x13\\x1d\\x04)$-Ir$B 9\\x15,R(', 'rating': '6'},\n", - " Document {'id': '3', 'payload': None, 'title': 'Black Widow', 'genre': 'action', 'description': 'Natasha Romanoff confronts her dark past and family ties as she battles a new enemy.', 'vector': '/~\\x17+%\\x04-Z(Δ\\x1f?\\x1c\\x16$6:B\\x14$\\x1c\\r\\x1ff\\x0b#)\\x06\\'(6\\x1c&\\x13),\"&$*-y)&)E*R\\x00u\\x16$.\\x1d\\x07\\x14V\\x1dXn)-.)\\x1d\\'\\'*]J\\x13)\\'%{,Y\\x07*+D˪\\x11..(%\\x15))\"M!(\\x17\\n!R+\\x02E\\x1f ^,\\'&Ց$\\x10**\\x0f1(ڨ)rڬ)+&\\x17.\\x01 /\\x18oK,J)[*\\x06%T\\x1f8\\x00N#%K\\x16/(!)r(}\\x1eV,x`)d*j(#/z\\x1d/0\\x13?ӧ\\n(6(}$*%\\'-$d*\\'(\\x06\\x14\\x1e\\x13`(JY4#v,4T!<\\x02\\x00*$\\x17-\\'i5*\\x14+\\x18\\x19ҥi&($.\\x1c t\\x1a!)\\x0f,6۬7\\'A*\\x04\\x1f\\x08(\\x02\\x05)|&\\x00-k\\x7f&,⡡X.P!\\x0b)!(2(#Ѫ.\\x1e\\x94\\x10\\x1a\\x06`,j0}\\x15oG\\x06\\x1b\\'*0*ˮ\\'$8\\x0b-?-m/u)0\\x0eXt*~,ί)\\x1f,/D\\x10%v\\x00zl\\x1f٩j-̦2\\x1b,]$\\x0b\\'$)F\\',\\x13/&}.E(gK\\x14L\\x00硇R\\'Ȭժ+\\x1bb\\x1a\\x1d*\\x05\"j)#Ϊ1.k-7we\\x13\\x05\\'g\\x15rΥ\\t,)%!Ҩy-%f\\x1fwg*P,hRw\"*+1<\\x18\\x1c\\x1a)m(8)\"\\x0c*%,h*U', 'rating': '7'},\n", - " Document {'id': '4', 'payload': None, 'title': 'John Wick', 'genre': 'action', 'description': 'A retired hitman seeks vengeance against those who wronged him, leaving a trail of destruction in his wake.', 'vector': '\\x9b).\\x19$\\x1b\\r#Mդk\\'\\x03H(p\\x1f%2$.l$@:-/\\x11QSѥ\\x03*%թţ\\x1cޭO$*H#%%h$ʩ\\x0f!C+\\x00*fa((h(kx-y\\x1ch*ĢQ()d%\\\\,U(j,)E$\\x0e|$%,Q!^-* #*K+)$%1\\x10,˧*k.؟l5#()$ѯ\\x15,\\x0eϘd(\\x1c,窺;,4(!k\\x1d\\x19,\\x1d\\x00(&& \\x00y,#\\n\\'w%\\x16&a)&*y\\x11/$\"?#,ެP\\x08.ǥ(\\x17g#(5xi/,U*!#a(u(\\x0c\\x16\\x19T$.h1!0%%w\\x01,[\">N\\'A(4\\x19+\\x03Y\\x1f.\"\\x1e\\n:\\x1d-<\\x1e)\\x00P)D*ڦ\\x15%&ʨե&\\'\\x05\\x01\\t&+$$p,=\\x00\\x18#\\')\\x03,\\x1e,,t4>1/\\x1f#\\x10QM\"=-\\x0b̟],2\\x0b#)H-9.& V#h\\x1e\\'$\\x02$+0\\x16+.\\x06)\\'\\'-\\'d*E\\x1eŬ \\x061\\x14R)ƩVW*\\x10XI&ͫ\\x04\"#\\'ҭ\\x17,\\x0f\\x1fB)#\\'!ӟ\\x00\\x04ꕔ%\\x12 +!]m*\\x19%o--s\\x1e$(Nάܪ\\x1cq\"(,N*&\\x1eB) \\x0e(y%p)+\\x10?A,(\\'3ǮW $wt)+\"\\x0c)t)yY(!Ƥ0\\x0536\"', 'rating': '8'},\n", - " Document {'id': '6', 'payload': None, 'title': 'The Dark Knight', 'genre': 'action', 'description': 'Batman faces off against the Joker, a criminal mastermind who threatens to plunge Gotham into chaos.', 'vector': '\\n/)j &*,\\'l$rR(\\x1d;ѥZ%, (*]-|\\x1f\\x03k+v(+$\\x1d)֭(6#բ0E+0() =&$9Y+*}\\x12+m(\\x1c(\\x11$I!V.()\"\\'l)J),\\x12*O Р,V\\'X$Ϥ&\\'\\x1a,\\x11\\')\\'N*ʠ1\\'\\x1c-::DJ)%\\'}(4\\x1fg\\'+S\\x08\\\\\\x07-\\x1f\\x10 !,*L)0**d),\\n--G!\\x15O)[Ȫ\\x00u\\x05\\x11T,fS%8)0!ps0e\\x07,\\x0c\\'7\\x0e\\x19g\\x08 g%\\x04\"(l*#R-c_)G)*\\x1adĭM\\x15̨߬#y ($쬮#9~)S\\x7f\\x0b#*\\x1fr\\x1fǡ5T\"+\\x19\"4\\'\\x17),\\x7fQ*d)\\t/T\\n\\x1c#ҭ¬\\r%\\x19s)릶(j*\\x00&@q9#\\x1dʬ*Y\\x1f8,(,*+\\x14)H&Eȡ\\x01\\n\\x17*#!\\t*l&(&((0gJ+\\x02)x\\x1c*\\x0f+Z.<(\\r(a$\\n( r`\\x1d}\\x11]1\\')N*\\x14%u+d(/\\x18\\x1fz\\x07ު\\r)!דɧ$+?(\\x10.\\x1f\\x12*\\x07*\\x05+%\\x00T˪]!\\x03$s+;Il*x%t% ,Z\\x06\\x0f=\\x18ȮC >\\',*ߣ3,\\x1a/*R$(t,ǩ\\\\$*~(;+2K& \\x1c\"uT\\x1d\\\\\\x11)Pfz$M)\\x15,\\x0b*b\\x1e', 'rating': '9'},\n", - " Document {'id': '7', 'payload': None, 'title': 'Gladiator', 'genre': 'action', 'description': 'A betrayed Roman general seeks revenge against the corrupt emperor who murdered his family.', 'vector': '.+\\x93;m^)\\x7f*\\x19\\x1a*3#\\x01\\x02.~$\\x02+$\\x1f|)e+X\\x04\\x04(C7,p\\x05\\x05M|+%.\\'*.50\\'~+(*$\\'t&\\x1a\\x11.\\x01\\x12\\'Ц+ (,\\x13\\'\\x1aWX\\';? \\x1c/Z+x\\x1d\\x1c\\x1a)\\x0f%jqT\\x14s*7\\x1e[*Fo,\\x0c0*hW*̠]-++h(o\\x1ebh)*\\x16\\x003\\x1clb!)*\\x0b\\x1dy.\\x1f@+,vV.,\\x197&(%[\\x1dQ(&\\'-(I#E!0$ЬU.X(-t(\\x1c&z$jED\\x1c(,$;\\x1cP*))\"),\\',(`^a$M5,\\x13\\x18a|(W9Ԯ\\x1e#i$\"\\x9d\\x08ޙ*\\x03!sì.l\\x00S\\x1f\\n$*\\x07!2k7\\'\\x1a$],V(ɪP0%##\\x1fj&\"z\\x0f).((,\\x0f,P#\\x01(G\\x1c./,\\x0bҡ$,\\'j,-˦)\\x08&h\\')&.\\x08.k(.v$̦\\'T\\x10$-Q(:r!(\\x07%O\\x1e\\'!,f-)*A\\x0f)B%t*}\\x0f,\\n.\\x1b-c\\x0c( .})\\x00\\x0c9&7\\x0f֬\\x1b\\x1f,!+\\r,\\x16%\\x1e\\\\\\x1cX\\x16\\x0f\\'ĥ\\x00-G\"\\x1e٥V, *̠!U,|+X\\',&m\\x02\\x01*,ʤQ\\x1d%,l\\x1a\\x15o*\\x12.(w#e\\x14', 'rating': '8'},\n", - " Document {'id': '8', 'payload': None, 'title': 'Inception', 'genre': 'action', 'description': 'A thief who enters dreams to steal secrets faces his toughest mission yet, with reality itself at stake.', 'vector': '**6$\\x18!\"&T+\\x1d١.$\"\\x0e3(%\\x01&*1\\x02**d\\')Щ\\uf805\\x1a-1*%+7էC \\x1c+ܡߡ\\x0f$\\x07**$~\\x1d(+ܫw($)[-\\x17\\x04+\\x0f(G2X-\\x1a+ףsp$%,hIf\\'\\x1cOg!-LA\\x10\\x0b#;\\n\\x03XR&,N-+Jx\\x1f;\\x00ܠ*!?#d(a&iAw\\x15Q.|\\'4*_8,a\\x14/Q8\\x0c*E9\\x1dW)m\\x1b\\x1d,N*&*-K*Wjh2\\'\\x11\\x15g&(\\x10)(\\x1aR\\x16\\x14\\x11),\\x00)9-\\x19*\\x17\\x19#-˨4\\x1aK\\x07ΩݦO&\\x02,\\x1f\\x0b7\\x05x(!\"-g%q\\x03@)\\':\\x07$\\x1d\\x00j-\\x16x\\'r,\\t,7\"\\x1e}*%)/\\r\\n*\\x06q #((\\n(N,o\\x16NE\\x1f߭M%aO-I[\\'y\\x11ħh\\\\\\\\,\\x1c,,\\x00-h)F)\\x03$\\x1b&s\\x1b()@+n%R\")(%`!.\\r)6-\\x11B&.!A((\\x13\\x1c,%J>*N(.ɫ\\x1b\\x08t$S\\x00{2+n*\\x02&W1K,*p\\'g)\\x19\\x18Ț)#-\"~\\'m# X0[&ɪd(\\x0e%6+)D&\\x13,\\x1d(,(\\x7f䧨,ʫ+\\x1eS\\'?\\x18\\x04-,m$M#4(^[\\x1c+\\x05\"\\x15\\x01', 'rating': '9'},\n", - " Document {'id': '9', 'payload': None, 'title': 'The Avengers', 'genre': 'action', 'description': \"Earth's mightiest heroes come together to stop an alien invasion that threatens the entire planet.\", 'vector': '&\\')\\x1b-0¨ȧ,=)\\x1c㞌)O\\x18\\'yu/4(-g+P!c\\x12\\x1dԧt$1\\x03*| m*\\x0fX&Ȭ[\\x1e\\x04\\x1cŬaC#p\\'Ϣ߫,w**\\x14ᠸ\\x1f$˥\\x1ff\\x1b*/\\x0c)\"\\x15<\\x14zc+,9%\\',[]&a\\x16@)4+$`-C+*ӣҪ&: w\\x195F&p \\x7f\\x1d>*0x*B\\x1d`**,)0\\x04\\t*$\\x07)|,x\\x12\\x00G\\x1b\\x1f(\\x1e&l\\x04-)C#_=)\\x0e(\\x1e$i(6\"C4\\x7f+\\x11(\\x03#!,Ξ\\x13J,Q-\"$&?(h+T,S\\x0c,j$d&+XT!f!\\x1b\\'\\x0c\\x1b%\\x18*\\x05+X)\\x1cΰ-%@\\x1f{--04\\t&$(\"X$w)\\x1cy zZ)y$)\\x02K\\x00\\x00˨\\x04\\x1a)\\x00/+)kr*\\x0f,\\x14?,:/\"M&`-(#\\ue840,#((@(\\x160\\x00-e!}C>\"()\\'\\x05+\\',\\x1d,\\x04w),m(a=+\\x1a-*\\'X,(\\x16ק!a,\\x18*+៥ڨs)\\x15?u\\x13$l\\x00~\\x1c,HX)(', 'rating': '8'}]" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "res.docs" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Does work with pure redis client.\n", - "client.memory_usage('rvl:37f6b0ea780c4a84a156f35f54a31c7e')" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.9" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/python-recipes/vector-search/03_float16_support.ipynb b/python-recipes/vector-search/03_float16_support.ipynb new file mode 100644 index 0000000..eab5ac7 --- /dev/null +++ b/python-recipes/vector-search/03_float16_support.ipynb @@ -0,0 +1,587 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![Redis](https://redis.io/wp-content/uploads/2024/04/Logotype.svg?auto=webp&quality=85,75&width=120)\n", + "# Using smaller vector types\n", + "\n", + "With the [Redis 7.4 release](https://redis.io/blog/announcing-redis-community-edition-and-redis-stack-74/) there is now support for bfloat16 and float16 data types in the vector store.\n", + "\n", + "This tutorial will walk through how you can convert data stored in an existing index from float32 vectors to float16.\n", + "\n", + "## Version requirements\n", + "\n", + "- redisvl >= 0.3.4\n", + "- redis >= 7.4.0\n", + "\n", + "## Packages" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m24.0\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.3.1\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n", + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "# NBVAL_SKIP\n", + "%pip install -q 'redis>=5.0.8' 'redisvl>=0.3.4' numpy sentence-transformers" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "import redisvl\n", + "assert redisvl.__version__ >= '0.3.4'" + ] + }, + { + "attachments": { + "image-2.png": { + "image/png": "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" + }, + "image.png": { + "image/png": "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epXyBZCXS0IAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAIFIAaZ1ihThMwIIIIAAAggggAACCCCAAAIIIIAAAggggAACCOxUAYITO5WXgyOAAAIIIIAAAggggAACCCCAAAIIIIAAAggggECkAMGJSBE+I4AAAggggAACCCCAAAIIIIAAAggggAACCCCAwE4VIDixU3k5OAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCEQKEJyIFOEzAggggAACCCCAAAIIIIAAAggggAACCCCAAAII7FQBghM7lZeDI4AAAggggAACCCCAAAIIIIAAAggggAACCCCAQKQAwYlIET4jgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIDAThUgOLFTeTk4AggggAACCCCAAAIIIIAAAggggAACCCCAAAIIRAoQnIgU4TMCCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgjsVAGCEzuVl4MjgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIBApADBiUgRPiOAAAIIIIAAAggggAACCCCAAAIIIIAAAggggMBOFSA4sVN5OTgCCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAghEChCciBThMwIIIIAAAggggAACCCCAAAL/Z+8s4KM42jD+YgECwV2Du7u7u7u7O21xaKEU+XB3d3f3IoXiUtzdJZAg/eaZY4+74y45IjQhz9vfZXdnZ2dn/3vldl8lARIgARIgARIgARIggQAlQONEgOLl4CRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAArYEaJywJcJtEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiCBACVSNIweAABAAElEQVRA40SA4uXgJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACtgRonLAlwm0SIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIIEAJUDjRIDi5eAkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAK2BGicsCXCbRIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIggQAlQONEgOLl4CRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAArYEaJywJcJtEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiCBACVA40SA4uXgJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACtgRonLAlwm0SIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIIEAJUDjRIDi5eAkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAK2BGicsCXCbRIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIggQAlQONEgOLl4CRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAArYEaJywJcJtEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiCBACVA40SA4uXgJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACtgRonLAlwm0SIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIIEAJUDjRIDi5eAkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAK2BGicsCXCbRIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIggQAlQONEgOLl4CRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAArYEaJywJcJtEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiCBACVA40SA4uXgJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACtgRonLAlwm0SIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIIEAJUDjRIDi5eAkQAIkQAIkQAIkQAIkQAIkQAIkQAL3H70gBBIgARIgARIgARKwIkDjhBUObpAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACQQ0ARonApowxycBEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABErAiQOOEFQ5ukAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJBDSBH8o48f79B8HHO/nw4aN4enl518VP+zC+T3Pw0wl4sBw68reMmTDNTALblmK5bbtueZzlMX5Z//jpk+C+2wraPnz8ZNustz99+lfe2znG6Ozp9V7Qx1LQ/9a9J/LqzTvLZq6TAAmQAAmQAAmQAAmQAAmQAAkEEAG8173z9DR/vNS7mn/J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EVQBY9WnbPWmurD25pWzJX7c2LpbCAmh/pEPZRzCpTMEEDXR5V9TTxgd8FlWxGSwMFI2YYkP2rEfxghETBgGDN9EXqgzIrcj6j7ULIsQDPsCDwZ4IGxTqZoMQW0JSJmC1g8GaMuRManAiJE2eXyJrDwbLKVf+yqSK3MyWbrxsPQYukh6/rFYFq09KEjxNGd4K0FNCwoJkAAJkAAJkAAJkAAJkAAJkMD3JVC/ZmXtCNlr0Ah94jbN6svYYf1krEornSJLEUmfu7SgkHbh/KZ3x17d2kqnNk1kzKRZkq1QRdmwZZdMGKHeVS0E+gFDELGwc++fkipbcYmaKLNUrddGH1+q6Bedg9HXWELPUKtqOb3ZrGEto1kvfdKB2NNN+DQHS72Js/oPq0l93rCs3WlvP9tMBC7feCDHz12XOhXyiKsyGtiTC1fvyWkV9eBILL9j6PPx40e5popmX7n5UB+CbOb9O1SR1MniyRBVH/Pn4Uu0rmxwtxoSKWJ4R8OynQRIgAR8TSDEyzcen7W8vhvDzTXo/+OE/IuoAwGPBt8I6lXAc8I7IwMKYH369K/u55tz8BhvCNzerawG6mMpCQubtgxjhOW+ILqOAlSeyugRPUrEIHoFnDYJkAAJkAAJkAAJkAAJkEBwJXD/0QuJE9Ox1/+PxAV1IVCT0lJ5b1wflMEeb9/ptEtGm3dL9H31+rWgXoWt06V3x3m371t1IN86B+o/vKMfdPZ9UAXg36vvK50ig84940xJICgSoHEiKN41zpkESIAESIAESIAESIAESIAESIAEghCB4GScCEK3hVMlARIgARIggf+UgHWuo/90Kjw5CZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZBAcCBA40RwuMu8RhIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIIRARonAhEN4NTIQESIAESIAESIAESIAESIAESIAESIAESIAESIAESIIHgQIDGieBwl3mNJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJBCICNA4EYhuBqdCAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAsGBAI0TweEu8xpJgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIIBARoHEiEN0MToUESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAEggMBGieCw13mNZIACZAACZAACZAACZAACZAACZAACZAACZAACZAACZBAICJA40QguhmcCgmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAkEBwI0TgSHu8xrJAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIIFARIDGiUB0MzgVEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEggOBGicCA53mddIAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAoGIAI0TgehmcCokQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkEBwI0DgRHO4yr5EESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAEAhEBGicC0c3gVEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEggOBCgcSI43GVeIwmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAkEIgI0TgSim8GpkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkEBwIEDjRHC4y7xGEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEghEBGicCEQ3g1MhARIgARIgARIgARIgARIgARIgARIgARIgARIgARIggeBAgMaJ4HCXeY0kQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkEIgI0DgRiG4Gp0ICJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACwYFA6OBwkbzGH4vAvUcv5Pb9Z/LitYd8+vSvv15cyJAhJHJEV0kQJ6rEjRnZX8fmYCRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiYCNE7wmxCkCPxz/b6cPn1NDuw8KieOX5QQIULIa2WkcHUNL2/fvpNQoULKx4+fxMUljLS8/5eE+/Thm64vVLhwEipXdrlUoZK8zJpeUrnH+abj2ZkESIAESIAESIAESIAESIAESIAESIAESIAESIAESMBnAjRO+MyIPQIJAURMnD17XVYt2iZv33lKuHBhJUWKhHLy1CVJmTKR3Lx1Xxsl3nu9l4gq+iFNxcYSwSWUr2Yf8u51eRkrhtyLEJ4RFL4iyINIgARIgARIgARIgARIgARIgARIgARIgARIgARIwDEBGicc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PLY2Po7tzbVXvrJ/J0CAAIFmgcpxorlwtxMgQIAAAQIECBAgQIAAgVkLGCdmLe79CBAgQIBAvsDLf2gw/yYJCRAgQIAAAQIECBAgQIAAAQIECBAgQIAAgWAB40RwOaIRIECAAAECBAgQIECAAAECBAgQIECAAIF5FDBOzGOrbiJAgAABAgQIECBAgAABAkECS4sLQWlEIUCAAAECBBIEjBMJLchAgAABAgQIECBAgAABAgQIECBAgAABAgSKBIwTRWU7lQABAgQIECBAgAABAgQIECBAgAABAgQIJAgYJxJakIEAAQIECBAgQIAAAQIECBAgQIAAAQIECBQJGCeKynYqAQIECBAgQIAAAQIECBAgQIAAAQIECBBIEDBOJLQgAwECBAgQIECAAAECBAgQIECAAAECBAgQKBIwThSV7VQCBAgQIECAAAECBAgQIECAAAECBAgQIJAgYJxIaEEGAgQIECBAgAABAgQIECBAgAABAgQIECBQJGCcKCrbqQQIECBAgAABAgQIECBAgAABAgQIECBAIEHAOJHQggwECBAgQIAAAQIECBAgQIAAAQIECBAgQKBIwDhRVLZTCRAgQIAAAQIECBAgQIAAAQIECBAgQIBAgoBxIqEFGQgQIECAAAECBAgQIECAAAECBAgQIECAQJGAcaKobKcSIECAAAECBAgQIECAAAECBAgQIECAAIEEAeNEQgsyECBAgAABAgQIECBAgAABAgQIECBAgACBIgHjRFHZTiVAgAABAgQIECBAgAABAgQIECBAgAABAgkCxomEFmQgQIAAAQIECBAgQIAAAQIECBAgQIAAAQJFAsaJorKdSoAAAQIECBAgQIAAAQIECBAgQIAAAQIEEgSMEwktyECAAAECBAgQIECAAAECBAgQIECAAAECBIoEjBNFZTuVAAECBAgQIECAAAECBAgQIECAAAECBAgkCBgnElqQgQABAgQIECBAgAABAgQIECBAgAABAgQIFAkYJ4rKdioBAgQIECBAgAABAgQIECBAgAABAgQIEEgQME4ktCADAQIECBAgQIAAAQIECBAgQIAAAQIECBAoEjBOFJXtVAIECBAgQIAAAQIECBAgQIAAAQIECBAgkCBgnEhoQQYCBAgQIECAAAECBAgQIECAAAECBAgQIFAkYJwoKtupBAgQIECAAAECBAgQIECAAAECBAgQIEAgQcA4kdCCDAQIECBAgAABAgQIECBAgAABAgQIECBAoEjAOFFUtlMJECBAgAABAgQIECBAgAABAgQIECBAgECCgHEioQUZCBAgQIAAAQIECBAgQIAAAQIECBAgQIBAkYBxoqhspxIgQIAAAQIECBAgQIAAAQIECBAgQIAAgQQB40RCCzIQIECAAAECBAgQIECAAAECBAgQIECAAIEiAeNEUdlOJUCAAAECBAgQIECAAAECBAgQIECAAAECCQLGiYQWZCBAgAABAgQIECBAgAABAgQIECBAgAABAkUCxomisp1KgAABAgQIECBAgAABAgQIECBAgAABAgQSBIwTCS3IQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEigSME0VlO5UAAQIECBAgQIAAAQIECBAgQIAAAQIECCQIfEgIMWW4ufufEkUOAgQIECBAgAABAgQIECBAgAABAgQIECBA4A0FYsaJpcWFNzzTSxMgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIpAn7WKaUJOQgQIECAAAECBAgQIECAAAECBAgQIECAQImAcaKkaGcSIECAAAECBAgQIECAAAECBAgQIECAAIEUAeNEShNyECBAgAABAgQIECBAgAABAgQIECBAgACBEgHjREnRziRAgAABAgQIECBAgAABAgQIECBAgAABAikCxomUJuQgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIlAsaJkqKdSYAAAQIECBAgQIAAAQIECBAgQIAAAQIEUgSMEylNyEGAAAECBAgQIECAAAECBAgQIECAAAECBEoEjBMlRTuTAAECBAgQIECAAAECBAgQIECAAAECBAikCBgnUpqQgwABAgQIECBAgAABAgQIECBAgAABAgQIlAgYJ0qKdiYBAgQIECBAgAABAgQIECBAgAABAgQIEEgRME6kNCEHAQIECBAgQIAAAQIECBAgQIAAAQIECBAoETBOlBTtTAIECBAgQIAAAQIECBAgQIAAAQIECBAgkCJgnEhpQg4CBAgQIECAAAECBAgQIECAAAECBAgQIFAiYJwoKdqZBAgQIECAAAECBAgQIECAAAECBAgQIEAgRcA4kdKEHAQIECBAgAABAgQIECBAgAABAgQIECBAoETAOFFStDMJECBAgAABAgQIECBAgAABAgQIECBAgECKgHEipQk5CBAgQIAAAQIECBAgQIAAAQIECBAgQIBAiYBxoqRoZxIgQIAAAQIECBAgQIAAAQIECBAgQIAAgRQB40RKE3IQIECAAAECBAgQIECAAAECBAgQIECAAIESgXumrFovOTRS3gAAAABJRU5ErkJggg==" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Check Redis Version\n", + "\n", + "### Redis cloud\n", + "![image.png](attachment:image.png)\n", + "\n", + "### Redis insight\n", + "![image-2.png](attachment:image-2.png)\n", + "\n", + "### Docker\n", + "\n", + "See [docker tags](https://hub.docker.com/_/redis/tags)\n", + "\n", + "## Connect to index by defining REDIS_URL" + ] + }, + { + "cell_type": "code", + "execution_count": 148, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "\n", + "# Replace values below with your own if using Redis Cloud instance\n", + "REDIS_HOST = os.getenv(\"REDIS_HOST\", \"localhost\") # ex: \"redis-18374.c253.us-central1-1.gce.cloud.redislabs.com\"\n", + "REDIS_PORT = os.getenv(\"REDIS_PORT\", \"6379\") # ex: 18374\n", + "REDIS_PASSWORD = os.getenv(\"REDIS_PASSWORD\", \"\") # ex: \"1TNxTEdYRDgIDKM2gDfasupCADXXXX\"\n", + "\n", + "# If SSL is enabled on the endpoint, use rediss:// as the URL prefix\n", + "REDIS_URL = f\"redis://:{REDIS_PASSWORD}@{REDIS_HOST}:{REDIS_PORT}\"" + ] + }, + { + "cell_type": "code", + "execution_count": 149, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 149, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# from redis import Redis\n", + "import redis\n", + "\n", + "client = redis.Redis.from_url(REDIS_URL)\n", + "client.ping()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Example setup\n", + "\n", + "If you already have an index populated you can skip this setup but for this tutorial we will create a float32 based index to show how to convert." + ] + }, + { + "cell_type": "code", + "execution_count": 150, + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "\n", + "# load raw data\n", + "with open(\"resources/movies.json\", 'r') as file:\n", + " movies = json.load(file)" + ] + }, + { + "cell_type": "code", + "execution_count": 151, + "metadata": {}, + "outputs": [], + "source": [ + "from redisvl.schema import IndexSchema\n", + "from redisvl.index import SearchIndex\n", + "\n", + "index_name = \"movies32\"\n", + "\n", + "schema_32 = IndexSchema.from_dict({\n", + " \"index\": {\n", + " \"name\": index_name,\n", + " \"prefix\": index_name,\n", + " },\n", + " \"fields\": [\n", + " {\n", + " \"name\": \"title\",\n", + " \"type\": \"text\",\n", + " },\n", + " {\n", + " \"name\": \"description\",\n", + " \"type\": \"text\",\n", + " },\n", + " {\n", + " \"name\": \"genre\",\n", + " \"type\": \"tag\",\n", + " \"attrs\": {\n", + " \"sortable\": True\n", + " }\n", + " },\n", + " {\n", + " \"name\": \"rating\",\n", + " \"type\": \"numeric\",\n", + " \"attrs\": {\n", + " \"sortable\": True\n", + " }\n", + " },\n", + " {\n", + " \"name\": \"vector\",\n", + " \"type\": \"vector\",\n", + " \"attrs\": {\n", + " \"dims\": 384,\n", + " \"distance_metric\": \"cosine\",\n", + " \"algorithm\": \"hnsw\",\n", + " \"datatype\": \"float32\"\n", + " }\n", + " }\n", + " ]\n", + "})\n", + "\n", + "\n", + "index32 = SearchIndex(schema_32, client)\n", + "index32.create(overwrite=True, drop=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Embed movie description vectors" + ] + }, + { + "cell_type": "code", + "execution_count": 152, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/robert.shelton/.pyenv/versions/3.11.9/lib/python3.11/site-packages/huggingface_hub/file_download.py:1142: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`.\n", + " warnings.warn(\n" + ] + } + ], + "source": [ + "from redisvl.utils.vectorize import HFTextVectorizer\n", + "\n", + "\n", + "# load model for embedding our movie descriptions\n", + "hf = HFTextVectorizer(model=\"sentence-transformers/all-MiniLM-L6-v2\")\n", + "\n", + "embeddings_32 = hf.embed_many([movie[\"description\"] for movie in movies], dtype=\"float32\", as_buffer=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 153, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "b'\\x9bf|=\\x0e`\\n;\"\\x92\\xb7;<\\xcb~\\xbd\\xfad\\xce\\xbb\\xc3\\x16J=V\\xa7?=\\xedv\\x95\\xaa\\x1c=\\xfd\\xee\\x89<\\xbd\\xb0-<\\x82\\xb2\\x9f\\xbc[\\x0b\\xc3\\xbd\\x98NR=xl\\xf7\\xbcN>\\x17\\xbe#\\x12\\x05\\xb99u\\xbf<\\xb0\\xe0b\\xba\\xd3\\xa6\\xa8\\xbdx\\xdc\\xec\\xbcRc%=\\xe4\\xe7r\\xbb\\x1eOG=?(\\x85=o@\\xa2\\xbc2Z\\xd0\\xbdC%K\\xbd\\xb9\\xed\\x94\\xbcR\\xddH=\\x92&F<\\xc6*\\xec<\\x90\\xd8\\x8d\\xbd\\xcbZ\\x98<\\t\\xa3\\xa3=>g3\\xbd&\\xcd\\xbd\\xbd\\x95$\\xf7;\\xfd\\xf4z=\\xfc\\xb4\\x8c=\\x85\\x0e\\xc6\\xbdnI\\x90\\xbdJ\\x16\\xbd;s\\xe7\\x0c\\xbd 3\\xc9\\xbc\\x85\\xf8\\xbb\\xbc\\xbf&u\\xbb5\\x8f\\xca<\\x05\\x80J=\\x0f\\xaf*=\\x8bOU\\xbd\\xc8\\xf0\\x95\\xbc\\x1d\\x02\\x19=)\\xf4K<\\xcb\\xc2\\t=F\\x83\\xac=\\x9f\\xd7\\xb8\\xbd\\xf2\\xb5\\x9c\\xbdB\\x85\\x18=\\x96d&=-3\\xf8<\\xfa\\xf7\\x88<\\x16v\\xf2\\xbb-=[\\xbd\\xf7\\xac\\xee\\xbb5:A\\xbd\\xd9d\\x19\\xbdrd\\xf2\\xbb!\\xbax;\\xdc;O<\\xb61,\\xbc\\xed\\xae\\xae=^\\x00-\\xbc\\x1a\\x06\\xae\\xbda\\xd6\\x1a=\\xcc\\xbf\\xcd=\\x1f\\x150=\\xcf\\xf1\\x9d\\xbc\\xa9GK=\\xaa\\xb8 =\\xb4\\xf1I\\xbd\"e\\x9e\\xbbF\\x8b\\xf7:\\x94\\xf8\\x1c=\\xa9\\xba\\xde<\\xcco\\x16\\xbb\\xe6]p\\xbb\\xbb\\xd5<<\\xac\\x95\\xa3\\xb8\\xc29s<&4&\\x10\\x90\\xbbvt\\xb9\\xbb\\x00\\xc9\\xb9\\xbb\\xfehk=\\x9a\\r\\xad<3f\\xa8\\xbd\\xbd]\\xcc=\\x15\\xe0 \\xbe\\xc74/\\xbd{f\\xf7\\xbcQ\\x9av=\\x11\\x0cq<,\\xda\\x1c\\xbd\\x01\\t\\x8b<\\xf0n\\xa6\\xbc\\xe4t\\x86<\\x82\\x87\\x19=v\\xae\\xe4\\xbc4m^\\xbc\\nV\\x0e\\xbd\\x81\\xb0\\xe3\\xbc\\xd3FU;\\xaaG|\\xbdW\\xfb\\x8b\\xbd\\x7f\\x81*\\xbdy\\x83\\xf4={\\xb7\\x10;\\x15!\\x0e\\xbd\\xfa\\xd3\\xb4=\\x15&\\x15\\xbdM\\x86\\x83=m$:\\xbdv\\x1bF\\xbd\\xa2?\\x14\\xbe\\xc5\\x8f(\\xbd\\xe3O\\x89\\xbd\\x17\\xae\\xd4<\\xa3\\x12\\xc3=\\xaf\\x05O\\xbd\\x7f\\x8ep\\xbc!\\xb5\\xac\\xbc\\xc4\\x9ee\\xbd9\\x8es;[a\\xc1;\\xd2\\xfaB\\xbd\\xf9#\\xfe:\\x90\\xe6\\xf4=\\xb2\\x15*<~\\xf8\\x1b=\\x01\\xfcV\\xbd\\xcf\\xd1\\r=*\\xee\\x06=\\x18u\\xba\\xbd\\x02\\xa4\\xd6<\\xf8\\xeb\\xd9;\\xc49/=\\xa8\\xc2\\x85=u\\x0b\"=\\xe9i\\xef<4\\xe8c=\\xfa2\\x08\\xbe\\xd4\\x12;=,VW;\\x15\\xa4b<\\xb0\\x9d\\xb7<\\x95r;\\xbd{z\\x91\\xbcI\\x00<\\xbd\\x18\\x1a\\xa3<\\xf9J%\\xbc\\n\\xe7\\xbf\\xbbr\\x87\\x12=\\x97\\x1d\\x95=\\x83|\\xfd\\xbc\\xed\\xf1\\xd1\\xbd%z\\x84;\\xcb\\tu=c\\x8ai\\xaa\\x1c=\\xfd\\xee\\x89<\\xbd\\xb0-<\\x82\\xb2\\x9f\\xbc[\\x0b\\xc3\\xbd\\x98NR=xl\\xf7\\xbcN>\\x17\\xbe#\\x12\\x05\\xb99u\\xbf<\\xb0\\xe0b\\xba\\xd3\\xa6\\xa8\\xbdx\\xdc\\xec\\xbcRc%=\\xe4\\xe7r\\xbb\\x1eOG=?(\\x85=o@\\xa2\\xbc2Z\\xd0\\xbdC%K\\xbd\\xb9\\xed\\x94\\xbcR\\xddH=\\x92&F<\\xc6*\\xec<\\x90\\xd8\\x8d\\xbd\\xcbZ\\x98<\\t\\xa3\\xa3=>g3\\xbd&\\xcd\\xbd\\xbd\\x95$\\xf7;\\xfd\\xf4z=\\xfc\\xb4\\x8c=\\x85\\x0e\\xc6\\xbdnI\\x90\\xbdJ\\x16\\xbd;s\\xe7\\x0c\\xbd 3\\xc9\\xbc\\x85\\xf8\\xbb\\xbc\\xbf&u\\xbb5\\x8f\\xca<\\x05\\x80J=\\x0f\\xaf*=\\x8bOU\\xbd\\xc8\\xf0\\x95\\xbc\\x1d\\x02\\x19=)\\xf4K<\\xcb\\xc2\\t=F\\x83\\xac=\\x9f\\xd7\\xb8\\xbd\\xf2\\xb5\\x9c\\xbdB\\x85\\x18=\\x96d&=-3\\xf8<\\xfa\\xf7\\x88<\\x16v\\xf2\\xbb-=[\\xbd\\xf7\\xac\\xee\\xbb5:A\\xbd\\xd9d\\x19\\xbdrd\\xf2\\xbb!\\xbax;\\xdc;O<\\xb61,\\xbc\\xed\\xae\\xae=^\\x00-\\xbc\\x1a\\x06\\xae\\xbda\\xd6\\x1a=\\xcc\\xbf\\xcd=\\x1f\\x150=\\xcf\\xf1\\x9d\\xbc\\xa9GK=\\xaa\\xb8 =\\xb4\\xf1I\\xbd\"e\\x9e\\xbbF\\x8b\\xf7:\\x94\\xf8\\x1c=\\xa9\\xba\\xde<\\xcco\\x16\\xbb\\xe6]p\\xbb\\xbb\\xd5<<\\xac\\x95\\xa3\\xb8\\xc29s<&4&\\x10\\x90\\xbbvt\\xb9\\xbb\\x00\\xc9\\xb9\\xbb\\xfehk=\\x9a\\r\\xad<3f\\xa8\\xbd\\xbd]\\xcc=\\x15\\xe0 \\xbe\\xc74/\\xbd{f\\xf7\\xbcQ\\x9av=\\x11\\x0cq<,\\xda\\x1c\\xbd\\x01\\t\\x8b<\\xf0n\\xa6\\xbc\\xe4t\\x86<\\x82\\x87\\x19=v\\xae\\xe4\\xbc4m^\\xbc\\nV\\x0e\\xbd\\x81\\xb0\\xe3\\xbc\\xd3FU;\\xaaG|\\xbdW\\xfb\\x8b\\xbd\\x7f\\x81*\\xbdy\\x83\\xf4={\\xb7\\x10;\\x15!\\x0e\\xbd\\xfa\\xd3\\xb4=\\x15&\\x15\\xbdM\\x86\\x83=m$:\\xbdv\\x1bF\\xbd\\xa2?\\x14\\xbe\\xc5\\x8f(\\xbd\\xe3O\\x89\\xbd\\x17\\xae\\xd4<\\xa3\\x12\\xc3=\\xaf\\x05O\\xbd\\x7f\\x8ep\\xbc!\\xb5\\xac\\xbc\\xc4\\x9ee\\xbd9\\x8es;[a\\xc1;\\xd2\\xfaB\\xbd\\xf9#\\xfe:\\x90\\xe6\\xf4=\\xb2\\x15*<~\\xf8\\x1b=\\x01\\xfcV\\xbd\\xcf\\xd1\\r=*\\xee\\x06=\\x18u\\xba\\xbd\\x02\\xa4\\xd6<\\xf8\\xeb\\xd9;\\xc49/=\\xa8\\xc2\\x85=u\\x0b\"=\\xe9i\\xef<4\\xe8c=\\xfa2\\x08\\xbe\\xd4\\x12;=,VW;\\x15\\xa4b<\\xb0\\x9d\\xb7<\\x95r;\\xbd{z\\x91\\xbcI\\x00<\\xbd\\x18\\x1a\\xa3<\\xf9J%\\xbc\\n\\xe7\\xbf\\xbbr\\x87\\x12=\\x97\\x1d\\x95=\\x83|\\xfd\\xbc\\xed\\xf1\\xd1\\xbd%z\\x84;\\xcb\\tu=c\\x8ai Date: Wed, 18 Dec 2024 16:52:52 -0500 Subject: [PATCH 3/5] remove bad comment --- python-recipes/vector-search/03_float16_support.ipynb | 1 - 1 file changed, 1 deletion(-) diff --git a/python-recipes/vector-search/03_float16_support.ipynb b/python-recipes/vector-search/03_float16_support.ipynb index eab5ac7..eb1469a 100644 --- a/python-recipes/vector-search/03_float16_support.ipynb +++ b/python-recipes/vector-search/03_float16_support.ipynb @@ -403,7 +403,6 @@ "\n", "index_name = \"movies16\"\n", "\n", - "# this won't work till we merge Justin's stuff\n", "schema16 = IndexSchema.from_dict({\n", " \"index\": {\n", " \"name\": index_name,\n", From 531e275c58da260724e36a9573fa2fad26e24ee2 Mon Sep 17 00:00:00 2001 From: Tyler Hutcherson Date: Wed, 18 Dec 2024 17:17:15 -0500 Subject: [PATCH 4/5] updates --- .../vector-search/03_float16_support.ipynb | 359 ++++++++++-------- 1 file changed, 199 insertions(+), 160 deletions(-) diff --git a/python-recipes/vector-search/03_float16_support.ipynb b/python-recipes/vector-search/03_float16_support.ipynb index eb1469a..eee5dd2 100644 --- a/python-recipes/vector-search/03_float16_support.ipynb +++ b/python-recipes/vector-search/03_float16_support.ipynb @@ -21,7 +21,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 1, "metadata": {}, "outputs": [ { @@ -29,7 +29,7 @@ "output_type": "stream", "text": [ "\n", - "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m24.0\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.3.1\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m24.2\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.3.1\u001b[0m\n", "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n", "Note: you may need to restart the kernel to use updated packages.\n" ] @@ -42,7 +42,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -79,7 +79,7 @@ }, { "cell_type": "code", - "execution_count": 148, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -96,7 +96,7 @@ }, { "cell_type": "code", - "execution_count": 149, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -105,7 +105,7 @@ "True" ] }, - "execution_count": 149, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -129,7 +129,7 @@ }, { "cell_type": "code", - "execution_count": 150, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -140,18 +140,33 @@ " movies = json.load(file)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create initial index" + ] + }, { "cell_type": "code", - "execution_count": 151, + "execution_count": 6, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "17:16:01 redisvl.index.index INFO Index already exists, overwriting.\n" + ] + } + ], "source": [ "from redisvl.schema import IndexSchema\n", "from redisvl.index import SearchIndex\n", "\n", - "index_name = \"movies32\"\n", + "index_name = \"movies\"\n", "\n", - "schema_32 = IndexSchema.from_dict({\n", + "schema = IndexSchema.from_dict({\n", " \"index\": {\n", " \"name\": index_name,\n", " \"prefix\": index_name,\n", @@ -193,8 +208,8 @@ "})\n", "\n", "\n", - "index32 = SearchIndex(schema_32, client)\n", - "index32.create(overwrite=True, drop=True)" + "index = SearchIndex(schema, client)\n", + "index.create(overwrite=True, drop=True)" ] }, { @@ -206,18 +221,9 @@ }, { "cell_type": "code", - "execution_count": 152, + "execution_count": 7, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/robert.shelton/.pyenv/versions/3.11.9/lib/python3.11/site-packages/huggingface_hub/file_download.py:1142: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`.\n", - " warnings.warn(\n" - ] - } - ], + "outputs": [], "source": [ "from redisvl.utils.vectorize import HFTextVectorizer\n", "\n", @@ -230,16 +236,16 @@ }, { "cell_type": "code", - "execution_count": 153, + "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "b'\\x9bf|=\\x0e`\\n;\"\\x92\\xb7;<\\xcb~\\xbd\\xfad\\xce\\xbb\\xc3\\x16J=V\\xa7?=\\xedv\\x95\\xaa\\x1c=\\xfd\\xee\\x89<\\xbd\\xb0-<\\x82\\xb2\\x9f\\xbc[\\x0b\\xc3\\xbd\\x98NR=xl\\xf7\\xbcN>\\x17\\xbe#\\x12\\x05\\xb99u\\xbf<\\xb0\\xe0b\\xba\\xd3\\xa6\\xa8\\xbdx\\xdc\\xec\\xbcRc%=\\xe4\\xe7r\\xbb\\x1eOG=?(\\x85=o@\\xa2\\xbc2Z\\xd0\\xbdC%K\\xbd\\xb9\\xed\\x94\\xbcR\\xddH=\\x92&F<\\xc6*\\xec<\\x90\\xd8\\x8d\\xbd\\xcbZ\\x98<\\t\\xa3\\xa3=>g3\\xbd&\\xcd\\xbd\\xbd\\x95$\\xf7;\\xfd\\xf4z=\\xfc\\xb4\\x8c=\\x85\\x0e\\xc6\\xbdnI\\x90\\xbdJ\\x16\\xbd;s\\xe7\\x0c\\xbd 3\\xc9\\xbc\\x85\\xf8\\xbb\\xbc\\xbf&u\\xbb5\\x8f\\xca<\\x05\\x80J=\\x0f\\xaf*=\\x8bOU\\xbd\\xc8\\xf0\\x95\\xbc\\x1d\\x02\\x19=)\\xf4K<\\xcb\\xc2\\t=F\\x83\\xac=\\x9f\\xd7\\xb8\\xbd\\xf2\\xb5\\x9c\\xbdB\\x85\\x18=\\x96d&=-3\\xf8<\\xfa\\xf7\\x88<\\x16v\\xf2\\xbb-=[\\xbd\\xf7\\xac\\xee\\xbb5:A\\xbd\\xd9d\\x19\\xbdrd\\xf2\\xbb!\\xbax;\\xdc;O<\\xb61,\\xbc\\xed\\xae\\xae=^\\x00-\\xbc\\x1a\\x06\\xae\\xbda\\xd6\\x1a=\\xcc\\xbf\\xcd=\\x1f\\x150=\\xcf\\xf1\\x9d\\xbc\\xa9GK=\\xaa\\xb8 =\\xb4\\xf1I\\xbd\"e\\x9e\\xbbF\\x8b\\xf7:\\x94\\xf8\\x1c=\\xa9\\xba\\xde<\\xcco\\x16\\xbb\\xe6]p\\xbb\\xbb\\xd5<<\\xac\\x95\\xa3\\xb8\\xc29s<&4&\\x10\\x90\\xbbvt\\xb9\\xbb\\x00\\xc9\\xb9\\xbb\\xfehk=\\x9a\\r\\xad<3f\\xa8\\xbd\\xbd]\\xcc=\\x15\\xe0 \\xbe\\xc74/\\xbd{f\\xf7\\xbcQ\\x9av=\\x11\\x0cq<,\\xda\\x1c\\xbd\\x01\\t\\x8b<\\xf0n\\xa6\\xbc\\xe4t\\x86<\\x82\\x87\\x19=v\\xae\\xe4\\xbc4m^\\xbc\\nV\\x0e\\xbd\\x81\\xb0\\xe3\\xbc\\xd3FU;\\xaaG|\\xbdW\\xfb\\x8b\\xbd\\x7f\\x81*\\xbdy\\x83\\xf4={\\xb7\\x10;\\x15!\\x0e\\xbd\\xfa\\xd3\\xb4=\\x15&\\x15\\xbdM\\x86\\x83=m$:\\xbdv\\x1bF\\xbd\\xa2?\\x14\\xbe\\xc5\\x8f(\\xbd\\xe3O\\x89\\xbd\\x17\\xae\\xd4<\\xa3\\x12\\xc3=\\xaf\\x05O\\xbd\\x7f\\x8ep\\xbc!\\xb5\\xac\\xbc\\xc4\\x9ee\\xbd9\\x8es;[a\\xc1;\\xd2\\xfaB\\xbd\\xf9#\\xfe:\\x90\\xe6\\xf4=\\xb2\\x15*<~\\xf8\\x1b=\\x01\\xfcV\\xbd\\xcf\\xd1\\r=*\\xee\\x06=\\x18u\\xba\\xbd\\x02\\xa4\\xd6<\\xf8\\xeb\\xd9;\\xc49/=\\xa8\\xc2\\x85=u\\x0b\"=\\xe9i\\xef<4\\xe8c=\\xfa2\\x08\\xbe\\xd4\\x12;=,VW;\\x15\\xa4b<\\xb0\\x9d\\xb7<\\x95r;\\xbd{z\\x91\\xbcI\\x00<\\xbd\\x18\\x1a\\xa3<\\xf9J%\\xbc\\n\\xe7\\xbf\\xbbr\\x87\\x12=\\x97\\x1d\\x95=\\x83|\\xfd\\xbc\\xed\\xf1\\xd1\\xbd%z\\x84;\\xcb\\tu=c\\x8ai\\xdb\\r\\xbd\\x92\\xf2H\\xbd\\x8ce\\xc6<;\\xdfa=t8\\x16\\xbc\\xe3\\xd3\\x13<9\\xaa\\x1c=\\x03\\xef\\x89<\\xb8\\xb0-<\\x9c\\xb2\\x9f\\xbcY\\x0b\\xc3\\xbd\\x9cNR=al\\xf7\\xbcM>\\x17\\xbe8\\x16\\x05\\xb9.u\\xbf<\\x7f\\xdfb\\xba\\xd4\\xa6\\xa8\\xbd}\\xdc\\xec\\xbcUc%=D\\xe7r\\xbb\\x1aOG=:(\\x85=q@\\xa2\\xbc1Z\\xd0\\xbdL%K\\xbd\\xce\\xed\\x94\\xbcQ\\xddH=\\xae&F<\\xcc*\\xec<\\x8b\\xd8\\x8d\\xbd\\xe0Z\\x98<\\x12\\xa3\\xa3=Dg3\\xbd&\\xcd\\xbd\\xbd\\xde$\\xf7;\\xf5\\xf4z=\\xfe\\xb4\\x8c=\\x8a\\x0e\\xc6\\xbdkI\\x90\\xbd\\x13\\x16\\xbd;y\\xe7\\x0c\\xbd\\x143\\xc9\\xbcz\\xf8\\xbb\\xbc\\\\&u\\xbb3\\x8f\\xca<\\xfa\\x7fJ=\\x13\\xaf*=\\x89OU\\xbd\\xdb\\xf0\\x95\\xbc\\x17\\x02\\x19=\\x17\\xf4K<\\xcc\\xc2\\t=D\\x83\\xac=\\x9c\\xd7\\xb8\\xbd\\xf0\\xb5\\x9c\\xbdC\\x85\\x18=\\x99d&=\\x1f3\\xf8<\\xde\\xf7\\x88<\\xbdv\\xf2\\xbb-=[\\xbd\\xb6\\xac\\xee\\xbb=:A\\xbd\\xd7d\\x19\\xbdpd\\xf2\\xbb\\xf9\\xb9x;\\x02\\xbdq\\x1bF\\xbd\\xa1?\\x14\\xbe\\xc8\\x8f(\\xbd\\xe7O\\x89\\xbd\\xfa\\xad\\xd4<\\xa5\\x12\\xc3=\\xb1\\x05O\\xbd\\x81\\x8ep\\xbc\\x11\\xb5\\xac\\xbc\\xb6\\x9ee\\xbd\\xf7\\x8ds;=a\\xc1;\\xce\\xfaB\\xbd\\xd9\"\\xfe:\\x8b\\xe6\\xf4=\\xaf\\x15*<\\x84\\xf8\\x1b=\\x0f\\xfcV\\xbd\\xd1\\xd1\\r=?\\xee\\x06=\\x14u\\xba\\xbd\\x00\\xa4\\xd6<2\\xec\\xd9;\\xbd9/=\\xa6\\xc2\\x85=}\\x0b\"=\\xeai\\xef<>\\xe8c=\\xfb2\\x08\\xbe\\xd2\\x12;=\\x97VW;!\\xa4b<\\xd1\\x9d\\xb7<\\x8ar;\\xbdyz\\x91\\xbcN\\x00<\\xbd1\\x1a\\xa3<\\xc4J%\\xbc\\x1c\\xe7\\xbf\\xbb\\x80\\x87\\x12=\\x95\\x1d\\x95=z|\\xfd\\xbc\\xf6\\xf1\\xd1\\xbd\\xf3y\\x84;\\xcb\\tu=$\\x8ai<9\\x91R\\xbd\\xcd\\xf3m\\xbd\\x89\\xb83=W\\xedF=\\x1f\\xf3\\xd1\\x08nA\\xba<\\x13\\xacO\\xbdb\\x0f\\xc7;\\x84\\xf4\\x04\\xbdG\\x82\\x92\\xbd\\x9d\\xddD=}\\xd8;\\xbc\\xd7;\\xf4\\xbc\\xb2\\x8f\\x97\\xbdF\\\\\\r\\xbd\\xe5\\x8c\\xf5\\xbd\\x8e\\x13(=\\x9a\\xc8\\xc6=\\xad\\xed\\x1a=\\x9c\\xa8\\xf8=\\xa7\\xc1\\xee\\xbc\\x11.\\x18\\xbb\\xce~;<\\xccF\\t\\xbd\\x1b\\x08\\x17=\\xa7\\xa5\\x1e=\\x1aK\\xcb\\xbd1\\xf7\\x8c\\xbdBb\\xed\\xbb\\x91[\\x19\\xbc0\\x0c\\x13\\xbckq\\x83=\\xe6wd\\xbdx\\xc7\\xd1\\xbb[lY\\xbc\\x9f|a=E\\xcf\\xfd\\xbc2\\xa5\\x83\\xbb\\xa5O\\x19\\xbd1\\x02]\\xbd\\xc0\\xeaz=\\xfe5\\x9c=7^\\xa9\\xbd\\x83^9\\xbcO\\xe4N\\xbc|\\x07x\\xbd\\x17{\\xa0=H\\x9f\\x96\\xaa\\x1c=\\xfd\\xee\\x89<\\xbd\\xb0-<\\x82\\xb2\\x9f\\xbc[\\x0b\\xc3\\xbd\\x98NR=xl\\xf7\\xbcN>\\x17\\xbe#\\x12\\x05\\xb99u\\xbf<\\xb0\\xe0b\\xba\\xd3\\xa6\\xa8\\xbdx\\xdc\\xec\\xbcRc%=\\xe4\\xe7r\\xbb\\x1eOG=?(\\x85=o@\\xa2\\xbc2Z\\xd0\\xbdC%K\\xbd\\xb9\\xed\\x94\\xbcR\\xddH=\\x92&F<\\xc6*\\xec<\\x90\\xd8\\x8d\\xbd\\xcbZ\\x98<\\t\\xa3\\xa3=>g3\\xbd&\\xcd\\xbd\\xbd\\x95$\\xf7;\\xfd\\xf4z=\\xfc\\xb4\\x8c=\\x85\\x0e\\xc6\\xbdnI\\x90\\xbdJ\\x16\\xbd;s\\xe7\\x0c\\xbd 3\\xc9\\xbc\\x85\\xf8\\xbb\\xbc\\xbf&u\\xbb5\\x8f\\xca<\\x05\\x80J=\\x0f\\xaf*=\\x8bOU\\xbd\\xc8\\xf0\\x95\\xbc\\x1d\\x02\\x19=)\\xf4K<\\xcb\\xc2\\t=F\\x83\\xac=\\x9f\\xd7\\xb8\\xbd\\xf2\\xb5\\x9c\\xbdB\\x85\\x18=\\x96d&=-3\\xf8<\\xfa\\xf7\\x88<\\x16v\\xf2\\xbb-=[\\xbd\\xf7\\xac\\xee\\xbb5:A\\xbd\\xd9d\\x19\\xbdrd\\xf2\\xbb!\\xbax;\\xdc;O<\\xb61,\\xbc\\xed\\xae\\xae=^\\x00-\\xbc\\x1a\\x06\\xae\\xbda\\xd6\\x1a=\\xcc\\xbf\\xcd=\\x1f\\x150=\\xcf\\xf1\\x9d\\xbc\\xa9GK=\\xaa\\xb8 =\\xb4\\xf1I\\xbd\"e\\x9e\\xbbF\\x8b\\xf7:\\x94\\xf8\\x1c=\\xa9\\xba\\xde<\\xcco\\x16\\xbb\\xe6]p\\xbb\\xbb\\xd5<<\\xac\\x95\\xa3\\xb8\\xc29s<&4&\\x10\\x90\\xbbvt\\xb9\\xbb\\x00\\xc9\\xb9\\xbb\\xfehk=\\x9a\\r\\xad<3f\\xa8\\xbd\\xbd]\\xcc=\\x15\\xe0 \\xbe\\xc74/\\xbd{f\\xf7\\xbcQ\\x9av=\\x11\\x0cq<,\\xda\\x1c\\xbd\\x01\\t\\x8b<\\xf0n\\xa6\\xbc\\xe4t\\x86<\\x82\\x87\\x19=v\\xae\\xe4\\xbc4m^\\xbc\\nV\\x0e\\xbd\\x81\\xb0\\xe3\\xbc\\xd3FU;\\xaaG|\\xbdW\\xfb\\x8b\\xbd\\x7f\\x81*\\xbdy\\x83\\xf4={\\xb7\\x10;\\x15!\\x0e\\xbd\\xfa\\xd3\\xb4=\\x15&\\x15\\xbdM\\x86\\x83=m$:\\xbdv\\x1bF\\xbd\\xa2?\\x14\\xbe\\xc5\\x8f(\\xbd\\xe3O\\x89\\xbd\\x17\\xae\\xd4<\\xa3\\x12\\xc3=\\xaf\\x05O\\xbd\\x7f\\x8ep\\xbc!\\xb5\\xac\\xbc\\xc4\\x9ee\\xbd9\\x8es;[a\\xc1;\\xd2\\xfaB\\xbd\\xf9#\\xfe:\\x90\\xe6\\xf4=\\xb2\\x15*<~\\xf8\\x1b=\\x01\\xfcV\\xbd\\xcf\\xd1\\r=*\\xee\\x06=\\x18u\\xba\\xbd\\x02\\xa4\\xd6<\\xf8\\xeb\\xd9;\\xc49/=\\xa8\\xc2\\x85=u\\x0b\"=\\xe9i\\xef<4\\xe8c=\\xfa2\\x08\\xbe\\xd4\\x12;=,VW;\\x15\\xa4b<\\xb0\\x9d\\xb7<\\x95r;\\xbd{z\\x91\\xbcI\\x00<\\xbd\\x18\\x1a\\xa3<\\xf9J%\\xbc\\n\\xe7\\xbf\\xbbr\\x87\\x12=\\x97\\x1d\\x95=\\x83|\\xfd\\xbc\\xed\\xf1\\xd1\\xbd%z\\x84;\\xcb\\tu=c\\x8ai\\xdb\\r\\xbd\\x92\\xf2H\\xbd\\x8ce\\xc6<;\\xdfa=t8\\x16\\xbc\\xe3\\xd3\\x13<9\\xaa\\x1c=\\x03\\xef\\x89<\\xb8\\xb0-<\\x9c\\xb2\\x9f\\xbcY\\x0b\\xc3\\xbd\\x9cNR=al\\xf7\\xbcM>\\x17\\xbe8\\x16\\x05\\xb9.u\\xbf<\\x7f\\xdfb\\xba\\xd4\\xa6\\xa8\\xbd}\\xdc\\xec\\xbcUc%=D\\xe7r\\xbb\\x1aOG=:(\\x85=q@\\xa2\\xbc1Z\\xd0\\xbdL%K\\xbd\\xce\\xed\\x94\\xbcQ\\xddH=\\xae&F<\\xcc*\\xec<\\x8b\\xd8\\x8d\\xbd\\xe0Z\\x98<\\x12\\xa3\\xa3=Dg3\\xbd&\\xcd\\xbd\\xbd\\xde$\\xf7;\\xf5\\xf4z=\\xfe\\xb4\\x8c=\\x8a\\x0e\\xc6\\xbdkI\\x90\\xbd\\x13\\x16\\xbd;y\\xe7\\x0c\\xbd\\x143\\xc9\\xbcz\\xf8\\xbb\\xbc\\\\&u\\xbb3\\x8f\\xca<\\xfa\\x7fJ=\\x13\\xaf*=\\x89OU\\xbd\\xdb\\xf0\\x95\\xbc\\x17\\x02\\x19=\\x17\\xf4K<\\xcc\\xc2\\t=D\\x83\\xac=\\x9c\\xd7\\xb8\\xbd\\xf0\\xb5\\x9c\\xbdC\\x85\\x18=\\x99d&=\\x1f3\\xf8<\\xde\\xf7\\x88<\\xbdv\\xf2\\xbb-=[\\xbd\\xb6\\xac\\xee\\xbb=:A\\xbd\\xd7d\\x19\\xbdpd\\xf2\\xbb\\xf9\\xb9x;\\x02\\xbdq\\x1bF\\xbd\\xa1?\\x14\\xbe\\xc8\\x8f(\\xbd\\xe7O\\x89\\xbd\\xfa\\xad\\xd4<\\xa5\\x12\\xc3=\\xb1\\x05O\\xbd\\x81\\x8ep\\xbc\\x11\\xb5\\xac\\xbc\\xb6\\x9ee\\xbd\\xf7\\x8ds;=a\\xc1;\\xce\\xfaB\\xbd\\xd9\"\\xfe:\\x8b\\xe6\\xf4=\\xaf\\x15*<\\x84\\xf8\\x1b=\\x0f\\xfcV\\xbd\\xd1\\xd1\\r=?\\xee\\x06=\\x14u\\xba\\xbd\\x00\\xa4\\xd6<2\\xec\\xd9;\\xbd9/=\\xa6\\xc2\\x85=}\\x0b\"=\\xeai\\xef<>\\xe8c=\\xfb2\\x08\\xbe\\xd2\\x12;=\\x97VW;!\\xa4b<\\xd1\\x9d\\xb7<\\x8ar;\\xbdyz\\x91\\xbcN\\x00<\\xbd1\\x1a\\xa3<\\xc4J%\\xbc\\x1c\\xe7\\xbf\\xbb\\x80\\x87\\x12=\\x95\\x1d\\x95=z|\\xfd\\xbc\\xf6\\xf1\\xd1\\xbd\\xf3y\\x84;\\xcb\\tu=$\\x8ai<9\\x91R\\xbd\\xcd\\xf3m\\xbd\\x89\\xb83=W\\xedF=\\x1f\\xf3\\xd1\\x08nA\\xba<\\x13\\xacO\\xbdb\\x0f\\xc7;\\x84\\xf4\\x04\\xbdG\\x82\\x92\\xbd\\x9d\\xddD=}\\xd8;\\xbc\\xd7;\\xf4\\xbc\\xb2\\x8f\\x97\\xbdF\\\\\\r\\xbd\\xe5\\x8c\\xf5\\xbd\\x8e\\x13(=\\x9a\\xc8\\xc6=\\xad\\xed\\x1a=\\x9c\\xa8\\xf8=\\xa7\\xc1\\xee\\xbc\\x11.\\x18\\xbb\\xce~;<\\xccF\\t\\xbd\\x1b\\x08\\x17=\\xa7\\xa5\\x1e=\\x1aK\\xcb\\xbd1\\xf7\\x8c\\xbdBb\\xed\\xbb\\x91[\\x19\\xbc0\\x0c\\x13\\xbckq\\x83=\\xe6wd\\xbdx\\xc7\\xd1\\xbb[lY\\xbc\\x9f|a=E\\xcf\\xfd\\xbc2\\xa5\\x83\\xbb\\xa5O\\x19\\xbd1\\x02]\\xbd\\xc0\\xeaz=\\xfe5\\x9c=7^\\xa9\\xbd\\x83^9\\xbcO\\xe4N\\xbc|\\x07x\\xbd\\x17{\\xa0=H\\x9f\\x96 Date: Thu, 19 Dec 2024 07:53:44 -0500 Subject: [PATCH 5/5] add boiler update readme --- README.md | 3 +- .../vector-search/03_float16_support.ipynb | 187 ++++++++++++------ 2 files changed, 124 insertions(+), 66 deletions(-) diff --git a/README.md b/README.md index 48ef403..4169218 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,8 @@ Need quickstarts to begin your Redis AI journey? **Start here.** | [/redis-intro/00_redis_intro.ipynb](/python-recipes/redis-intro/00_redis_intro.ipynb) | The place to start if brand new to Redis | | [/vector-search/00_redispy.ipynb](/python-recipes/vector-search/00_redispy.ipynb) | Vector search with Redis python client | | [/vector-search/01_redisvl.ipynb](/python-recipes/vector-search/01_redisvl.ipynb) | Vector search with Redis Vector Library | -| [/vector-search/02_hybrid_search.ipynb](/python-recipes/vector-search/02_hybrid_search.ipynb) | Hybrid search techniques with Redis (BM25 + Vector) +| [/vector-search/02_hybrid_search.ipynb](/python-recipes/vector-search/02_hybrid_search.ipynb) | Hybrid search techniques with Redis (BM25 + Vector) | +| [/vector-search/03_float16_support.ipynb](/python-recipes/vector-search/03_float16_support.ipynb) | Shows how to convert a float32 index to use float16 | ### Retrieval Augmented Generation (RAG) diff --git a/python-recipes/vector-search/03_float16_support.ipynb b/python-recipes/vector-search/03_float16_support.ipynb index eee5dd2..a2e89aa 100644 --- a/python-recipes/vector-search/03_float16_support.ipynb +++ b/python-recipes/vector-search/03_float16_support.ipynb @@ -16,6 +16,9 @@ "- redisvl >= 0.3.4\n", "- redis >= 7.4.0\n", "\n", + "## Let's Begin!\n", + "\"Open\n", + "\n", "## Packages" ] }, @@ -50,6 +53,45 @@ "assert redisvl.__version__ >= '0.3.4'" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Run Redis Stack\n", + "\n", + "For this tutorial you will need a running instance of Redis if you don't already have one.\n", + "\n", + "#### For Colab\n", + "Use the shell script below to download, extract, and install [Redis Stack](https://redis.io/docs/getting-started/install-stack/) directly from the Redis package archive." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# NBVAL_SKIP\n", + "%%sh\n", + "curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg\n", + "echo \"deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main\" | sudo tee /etc/apt/sources.list.d/redis.list\n", + "sudo apt-get update > /dev/null 2>&1\n", + "sudo apt-get install redis-stack-server > /dev/null 2>&1\n", + "redis-stack-server --daemonize yes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### For Alternative Environments\n", + "There are many ways to get the necessary redis-stack instance running\n", + "1. On cloud, deploy a [FREE instance of Redis in the cloud](https://redis.com/try-free/). Or, if you have your\n", + "own version of Redis Enterprise running, that works too!\n", + "2. Per OS, [see the docs](https://redis.io/docs/latest/operate/oss_and_stack/install/install-stack/)\n", + "3. With docker: `docker run -d --name redis-stack-server -p 6379:6379 redis/redis-stack-server:latest`" + ] + }, { "attachments": { "image-2.png": { @@ -64,6 +106,8 @@ "source": [ "## Check Redis Version\n", "\n", + "For this tutorial it's important to validate that your redis instance meets the version requirements you can do this through a number of the UI's available or check the docker tag your using itself.\n", + "\n", "### Redis cloud\n", "![image.png](attachment:image.png)\n", "\n", @@ -79,7 +123,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -96,7 +140,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -105,7 +149,7 @@ "True" ] }, - "execution_count": 4, + "execution_count": 2, "metadata": {}, "output_type": "execute_result" } @@ -129,7 +173,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -149,17 +193,9 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 4, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "17:16:01 redisvl.index.index INFO Index already exists, overwriting.\n" - ] - } - ], + "outputs": [], "source": [ "from redisvl.schema import IndexSchema\n", "from redisvl.index import SearchIndex\n", @@ -221,9 +257,20 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/robert.shelton/.pyenv/versions/3.11.9/lib/python3.11/site-packages/huggingface_hub/file_download.py:1142: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`.\n", + " warnings.warn(\n", + "/Users/robert.shelton/.pyenv/versions/3.11.9/lib/python3.11/site-packages/huggingface_hub/file_download.py:1142: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`.\n", + " warnings.warn(\n" + ] + } + ], "source": [ "from redisvl.utils.vectorize import HFTextVectorizer\n", "\n", @@ -236,16 +283,16 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "b'\\x94f|=\\xf1`\\n;\\x16\\x92\\xb7;1\\xcb~\\xbd7e\\xce\\xbb\\xcb\\x16J=Q\\xa7?=\\xe9v\\x95\\xdb\\r\\xbd\\x92\\xf2H\\xbd\\x8ce\\xc6<;\\xdfa=t8\\x16\\xbc\\xe3\\xd3\\x13<9\\xaa\\x1c=\\x03\\xef\\x89<\\xb8\\xb0-<\\x9c\\xb2\\x9f\\xbcY\\x0b\\xc3\\xbd\\x9cNR=al\\xf7\\xbcM>\\x17\\xbe8\\x16\\x05\\xb9.u\\xbf<\\x7f\\xdfb\\xba\\xd4\\xa6\\xa8\\xbd}\\xdc\\xec\\xbcUc%=D\\xe7r\\xbb\\x1aOG=:(\\x85=q@\\xa2\\xbc1Z\\xd0\\xbdL%K\\xbd\\xce\\xed\\x94\\xbcQ\\xddH=\\xae&F<\\xcc*\\xec<\\x8b\\xd8\\x8d\\xbd\\xe0Z\\x98<\\x12\\xa3\\xa3=Dg3\\xbd&\\xcd\\xbd\\xbd\\xde$\\xf7;\\xf5\\xf4z=\\xfe\\xb4\\x8c=\\x8a\\x0e\\xc6\\xbdkI\\x90\\xbd\\x13\\x16\\xbd;y\\xe7\\x0c\\xbd\\x143\\xc9\\xbcz\\xf8\\xbb\\xbc\\\\&u\\xbb3\\x8f\\xca<\\xfa\\x7fJ=\\x13\\xaf*=\\x89OU\\xbd\\xdb\\xf0\\x95\\xbc\\x17\\x02\\x19=\\x17\\xf4K<\\xcc\\xc2\\t=D\\x83\\xac=\\x9c\\xd7\\xb8\\xbd\\xf0\\xb5\\x9c\\xbdC\\x85\\x18=\\x99d&=\\x1f3\\xf8<\\xde\\xf7\\x88<\\xbdv\\xf2\\xbb-=[\\xbd\\xb6\\xac\\xee\\xbb=:A\\xbd\\xd7d\\x19\\xbdpd\\xf2\\xbb\\xf9\\xb9x;\\x02\\xbdq\\x1bF\\xbd\\xa1?\\x14\\xbe\\xc8\\x8f(\\xbd\\xe7O\\x89\\xbd\\xfa\\xad\\xd4<\\xa5\\x12\\xc3=\\xb1\\x05O\\xbd\\x81\\x8ep\\xbc\\x11\\xb5\\xac\\xbc\\xb6\\x9ee\\xbd\\xf7\\x8ds;=a\\xc1;\\xce\\xfaB\\xbd\\xd9\"\\xfe:\\x8b\\xe6\\xf4=\\xaf\\x15*<\\x84\\xf8\\x1b=\\x0f\\xfcV\\xbd\\xd1\\xd1\\r=?\\xee\\x06=\\x14u\\xba\\xbd\\x00\\xa4\\xd6<2\\xec\\xd9;\\xbd9/=\\xa6\\xc2\\x85=}\\x0b\"=\\xeai\\xef<>\\xe8c=\\xfb2\\x08\\xbe\\xd2\\x12;=\\x97VW;!\\xa4b<\\xd1\\x9d\\xb7<\\x8ar;\\xbdyz\\x91\\xbcN\\x00<\\xbd1\\x1a\\xa3<\\xc4J%\\xbc\\x1c\\xe7\\xbf\\xbb\\x80\\x87\\x12=\\x95\\x1d\\x95=z|\\xfd\\xbc\\xf6\\xf1\\xd1\\xbd\\xf3y\\x84;\\xcb\\tu=$\\x8ai<9\\x91R\\xbd\\xcd\\xf3m\\xbd\\x89\\xb83=W\\xedF=\\x1f\\xf3\\xd1\\x08nA\\xba<\\x13\\xacO\\xbdb\\x0f\\xc7;\\x84\\xf4\\x04\\xbdG\\x82\\x92\\xbd\\x9d\\xddD=}\\xd8;\\xbc\\xd7;\\xf4\\xbc\\xb2\\x8f\\x97\\xbdF\\\\\\r\\xbd\\xe5\\x8c\\xf5\\xbd\\x8e\\x13(=\\x9a\\xc8\\xc6=\\xad\\xed\\x1a=\\x9c\\xa8\\xf8=\\xa7\\xc1\\xee\\xbc\\x11.\\x18\\xbb\\xce~;<\\xccF\\t\\xbd\\x1b\\x08\\x17=\\xa7\\xa5\\x1e=\\x1aK\\xcb\\xbd1\\xf7\\x8c\\xbdBb\\xed\\xbb\\x91[\\x19\\xbc0\\x0c\\x13\\xbckq\\x83=\\xe6wd\\xbdx\\xc7\\xd1\\xbb[lY\\xbc\\x9f|a=E\\xcf\\xfd\\xbc2\\xa5\\x83\\xbb\\xa5O\\x19\\xbd1\\x02]\\xbd\\xc0\\xeaz=\\xfe5\\x9c=7^\\xa9\\xbd\\x83^9\\xbcO\\xe4N\\xbc|\\x07x\\xbd\\x17{\\xa0=H\\x9f\\x96\\xaa\\x1c=\\xfd\\xee\\x89<\\xbd\\xb0-<\\x82\\xb2\\x9f\\xbc[\\x0b\\xc3\\xbd\\x98NR=xl\\xf7\\xbcN>\\x17\\xbe#\\x12\\x05\\xb99u\\xbf<\\xb0\\xe0b\\xba\\xd3\\xa6\\xa8\\xbdx\\xdc\\xec\\xbcRc%=\\xe4\\xe7r\\xbb\\x1eOG=?(\\x85=o@\\xa2\\xbc2Z\\xd0\\xbdC%K\\xbd\\xb9\\xed\\x94\\xbcR\\xddH=\\x92&F<\\xc6*\\xec<\\x90\\xd8\\x8d\\xbd\\xcbZ\\x98<\\t\\xa3\\xa3=>g3\\xbd&\\xcd\\xbd\\xbd\\x95$\\xf7;\\xfd\\xf4z=\\xfc\\xb4\\x8c=\\x85\\x0e\\xc6\\xbdnI\\x90\\xbdJ\\x16\\xbd;s\\xe7\\x0c\\xbd 3\\xc9\\xbc\\x85\\xf8\\xbb\\xbc\\xbf&u\\xbb5\\x8f\\xca<\\x05\\x80J=\\x0f\\xaf*=\\x8bOU\\xbd\\xc8\\xf0\\x95\\xbc\\x1d\\x02\\x19=)\\xf4K<\\xcb\\xc2\\t=F\\x83\\xac=\\x9f\\xd7\\xb8\\xbd\\xf2\\xb5\\x9c\\xbdB\\x85\\x18=\\x96d&=-3\\xf8<\\xfa\\xf7\\x88<\\x16v\\xf2\\xbb-=[\\xbd\\xf7\\xac\\xee\\xbb5:A\\xbd\\xd9d\\x19\\xbdrd\\xf2\\xbb!\\xbax;\\xdc;O<\\xb61,\\xbc\\xed\\xae\\xae=^\\x00-\\xbc\\x1a\\x06\\xae\\xbda\\xd6\\x1a=\\xcc\\xbf\\xcd=\\x1f\\x150=\\xcf\\xf1\\x9d\\xbc\\xa9GK=\\xaa\\xb8 =\\xb4\\xf1I\\xbd\"e\\x9e\\xbbF\\x8b\\xf7:\\x94\\xf8\\x1c=\\xa9\\xba\\xde<\\xcco\\x16\\xbb\\xe6]p\\xbb\\xbb\\xd5<<\\xac\\x95\\xa3\\xb8\\xc29s<&4&\\x10\\x90\\xbbvt\\xb9\\xbb\\x00\\xc9\\xb9\\xbb\\xfehk=\\x9a\\r\\xad<3f\\xa8\\xbd\\xbd]\\xcc=\\x15\\xe0 \\xbe\\xc74/\\xbd{f\\xf7\\xbcQ\\x9av=\\x11\\x0cq<,\\xda\\x1c\\xbd\\x01\\t\\x8b<\\xf0n\\xa6\\xbc\\xe4t\\x86<\\x82\\x87\\x19=v\\xae\\xe4\\xbc4m^\\xbc\\nV\\x0e\\xbd\\x81\\xb0\\xe3\\xbc\\xd3FU;\\xaaG|\\xbdW\\xfb\\x8b\\xbd\\x7f\\x81*\\xbdy\\x83\\xf4={\\xb7\\x10;\\x15!\\x0e\\xbd\\xfa\\xd3\\xb4=\\x15&\\x15\\xbdM\\x86\\x83=m$:\\xbdv\\x1bF\\xbd\\xa2?\\x14\\xbe\\xc5\\x8f(\\xbd\\xe3O\\x89\\xbd\\x17\\xae\\xd4<\\xa3\\x12\\xc3=\\xaf\\x05O\\xbd\\x7f\\x8ep\\xbc!\\xb5\\xac\\xbc\\xc4\\x9ee\\xbd9\\x8es;[a\\xc1;\\xd2\\xfaB\\xbd\\xf9#\\xfe:\\x90\\xe6\\xf4=\\xb2\\x15*<~\\xf8\\x1b=\\x01\\xfcV\\xbd\\xcf\\xd1\\r=*\\xee\\x06=\\x18u\\xba\\xbd\\x02\\xa4\\xd6<\\xf8\\xeb\\xd9;\\xc49/=\\xa8\\xc2\\x85=u\\x0b\"=\\xe9i\\xef<4\\xe8c=\\xfa2\\x08\\xbe\\xd4\\x12;=,VW;\\x15\\xa4b<\\xb0\\x9d\\xb7<\\x95r;\\xbd{z\\x91\\xbcI\\x00<\\xbd\\x18\\x1a\\xa3<\\xf9J%\\xbc\\n\\xe7\\xbf\\xbbr\\x87\\x12=\\x97\\x1d\\x95=\\x83|\\xfd\\xbc\\xed\\xf1\\xd1\\xbd%z\\x84;\\xcb\\tu=c\\x8ai\\xdb\\r\\xbd\\x92\\xf2H\\xbd\\x8ce\\xc6<;\\xdfa=t8\\x16\\xbc\\xe3\\xd3\\x13<9\\xaa\\x1c=\\x03\\xef\\x89<\\xb8\\xb0-<\\x9c\\xb2\\x9f\\xbcY\\x0b\\xc3\\xbd\\x9cNR=al\\xf7\\xbcM>\\x17\\xbe8\\x16\\x05\\xb9.u\\xbf<\\x7f\\xdfb\\xba\\xd4\\xa6\\xa8\\xbd}\\xdc\\xec\\xbcUc%=D\\xe7r\\xbb\\x1aOG=:(\\x85=q@\\xa2\\xbc1Z\\xd0\\xbdL%K\\xbd\\xce\\xed\\x94\\xbcQ\\xddH=\\xae&F<\\xcc*\\xec<\\x8b\\xd8\\x8d\\xbd\\xe0Z\\x98<\\x12\\xa3\\xa3=Dg3\\xbd&\\xcd\\xbd\\xbd\\xde$\\xf7;\\xf5\\xf4z=\\xfe\\xb4\\x8c=\\x8a\\x0e\\xc6\\xbdkI\\x90\\xbd\\x13\\x16\\xbd;y\\xe7\\x0c\\xbd\\x143\\xc9\\xbcz\\xf8\\xbb\\xbc\\\\&u\\xbb3\\x8f\\xca<\\xfa\\x7fJ=\\x13\\xaf*=\\x89OU\\xbd\\xdb\\xf0\\x95\\xbc\\x17\\x02\\x19=\\x17\\xf4K<\\xcc\\xc2\\t=D\\x83\\xac=\\x9c\\xd7\\xb8\\xbd\\xf0\\xb5\\x9c\\xbdC\\x85\\x18=\\x99d&=\\x1f3\\xf8<\\xde\\xf7\\x88<\\xbdv\\xf2\\xbb-=[\\xbd\\xb6\\xac\\xee\\xbb=:A\\xbd\\xd7d\\x19\\xbdpd\\xf2\\xbb\\xf9\\xb9x;\\x02\\xbdq\\x1bF\\xbd\\xa1?\\x14\\xbe\\xc8\\x8f(\\xbd\\xe7O\\x89\\xbd\\xfa\\xad\\xd4<\\xa5\\x12\\xc3=\\xb1\\x05O\\xbd\\x81\\x8ep\\xbc\\x11\\xb5\\xac\\xbc\\xb6\\x9ee\\xbd\\xf7\\x8ds;=a\\xc1;\\xce\\xfaB\\xbd\\xd9\"\\xfe:\\x8b\\xe6\\xf4=\\xaf\\x15*<\\x84\\xf8\\x1b=\\x0f\\xfcV\\xbd\\xd1\\xd1\\r=?\\xee\\x06=\\x14u\\xba\\xbd\\x00\\xa4\\xd6<2\\xec\\xd9;\\xbd9/=\\xa6\\xc2\\x85=}\\x0b\"=\\xeai\\xef<>\\xe8c=\\xfb2\\x08\\xbe\\xd2\\x12;=\\x97VW;!\\xa4b<\\xd1\\x9d\\xb7<\\x8ar;\\xbdyz\\x91\\xbcN\\x00<\\xbd1\\x1a\\xa3<\\xc4J%\\xbc\\x1c\\xe7\\xbf\\xbb\\x80\\x87\\x12=\\x95\\x1d\\x95=z|\\xfd\\xbc\\xf6\\xf1\\xd1\\xbd\\xf3y\\x84;\\xcb\\tu=$\\x8ai<9\\x91R\\xbd\\xcd\\xf3m\\xbd\\x89\\xb83=W\\xedF=\\x1f\\xf3\\xd1\\x08nA\\xba<\\x13\\xacO\\xbdb\\x0f\\xc7;\\x84\\xf4\\x04\\xbdG\\x82\\x92\\xbd\\x9d\\xddD=}\\xd8;\\xbc\\xd7;\\xf4\\xbc\\xb2\\x8f\\x97\\xbdF\\\\\\r\\xbd\\xe5\\x8c\\xf5\\xbd\\x8e\\x13(=\\x9a\\xc8\\xc6=\\xad\\xed\\x1a=\\x9c\\xa8\\xf8=\\xa7\\xc1\\xee\\xbc\\x11.\\x18\\xbb\\xce~;<\\xccF\\t\\xbd\\x1b\\x08\\x17=\\xa7\\xa5\\x1e=\\x1aK\\xcb\\xbd1\\xf7\\x8c\\xbdBb\\xed\\xbb\\x91[\\x19\\xbc0\\x0c\\x13\\xbckq\\x83=\\xe6wd\\xbdx\\xc7\\xd1\\xbb[lY\\xbc\\x9f|a=E\\xcf\\xfd\\xbc2\\xa5\\x83\\xbb\\xa5O\\x19\\xbd1\\x02]\\xbd\\xc0\\xeaz=\\xfe5\\x9c=7^\\xa9\\xbd\\x83^9\\xbcO\\xe4N\\xbc|\\x07x\\xbd\\x17{\\xa0=H\\x9f\\x96\\xaa\\x1c=\\xfd\\xee\\x89<\\xbd\\xb0-<\\x82\\xb2\\x9f\\xbc[\\x0b\\xc3\\xbd\\x98NR=xl\\xf7\\xbcN>\\x17\\xbe#\\x12\\x05\\xb99u\\xbf<\\xb0\\xe0b\\xba\\xd3\\xa6\\xa8\\xbdx\\xdc\\xec\\xbcRc%=\\xe4\\xe7r\\xbb\\x1eOG=?(\\x85=o@\\xa2\\xbc2Z\\xd0\\xbdC%K\\xbd\\xb9\\xed\\x94\\xbcR\\xddH=\\x92&F<\\xc6*\\xec<\\x90\\xd8\\x8d\\xbd\\xcbZ\\x98<\\t\\xa3\\xa3=>g3\\xbd&\\xcd\\xbd\\xbd\\x95$\\xf7;\\xfd\\xf4z=\\xfc\\xb4\\x8c=\\x85\\x0e\\xc6\\xbdnI\\x90\\xbdJ\\x16\\xbd;s\\xe7\\x0c\\xbd 3\\xc9\\xbc\\x85\\xf8\\xbb\\xbc\\xbf&u\\xbb5\\x8f\\xca<\\x05\\x80J=\\x0f\\xaf*=\\x8bOU\\xbd\\xc8\\xf0\\x95\\xbc\\x1d\\x02\\x19=)\\xf4K<\\xcb\\xc2\\t=F\\x83\\xac=\\x9f\\xd7\\xb8\\xbd\\xf2\\xb5\\x9c\\xbdB\\x85\\x18=\\x96d&=-3\\xf8<\\xfa\\xf7\\x88<\\x16v\\xf2\\xbb-=[\\xbd\\xf7\\xac\\xee\\xbb5:A\\xbd\\xd9d\\x19\\xbdrd\\xf2\\xbb!\\xbax;\\xdc;O<\\xb61,\\xbc\\xed\\xae\\xae=^\\x00-\\xbc\\x1a\\x06\\xae\\xbda\\xd6\\x1a=\\xcc\\xbf\\xcd=\\x1f\\x150=\\xcf\\xf1\\x9d\\xbc\\xa9GK=\\xaa\\xb8 =\\xb4\\xf1I\\xbd\"e\\x9e\\xbbF\\x8b\\xf7:\\x94\\xf8\\x1c=\\xa9\\xba\\xde<\\xcco\\x16\\xbb\\xe6]p\\xbb\\xbb\\xd5<<\\xac\\x95\\xa3\\xb8\\xc29s<&4&\\x10\\x90\\xbbvt\\xb9\\xbb\\x00\\xc9\\xb9\\xbb\\xfehk=\\x9a\\r\\xad<3f\\xa8\\xbd\\xbd]\\xcc=\\x15\\xe0 \\xbe\\xc74/\\xbd{f\\xf7\\xbcQ\\x9av=\\x11\\x0cq<,\\xda\\x1c\\xbd\\x01\\t\\x8b<\\xf0n\\xa6\\xbc\\xe4t\\x86<\\x82\\x87\\x19=v\\xae\\xe4\\xbc4m^\\xbc\\nV\\x0e\\xbd\\x81\\xb0\\xe3\\xbc\\xd3FU;\\xaaG|\\xbdW\\xfb\\x8b\\xbd\\x7f\\x81*\\xbdy\\x83\\xf4={\\xb7\\x10;\\x15!\\x0e\\xbd\\xfa\\xd3\\xb4=\\x15&\\x15\\xbdM\\x86\\x83=m$:\\xbdv\\x1bF\\xbd\\xa2?\\x14\\xbe\\xc5\\x8f(\\xbd\\xe3O\\x89\\xbd\\x17\\xae\\xd4<\\xa3\\x12\\xc3=\\xaf\\x05O\\xbd\\x7f\\x8ep\\xbc!\\xb5\\xac\\xbc\\xc4\\x9ee\\xbd9\\x8es;[a\\xc1;\\xd2\\xfaB\\xbd\\xf9#\\xfe:\\x90\\xe6\\xf4=\\xb2\\x15*<~\\xf8\\x1b=\\x01\\xfcV\\xbd\\xcf\\xd1\\r=*\\xee\\x06=\\x18u\\xba\\xbd\\x02\\xa4\\xd6<\\xf8\\xeb\\xd9;\\xc49/=\\xa8\\xc2\\x85=u\\x0b\"=\\xe9i\\xef<4\\xe8c=\\xfa2\\x08\\xbe\\xd4\\x12;=,VW;\\x15\\xa4b<\\xb0\\x9d\\xb7<\\x95r;\\xbd{z\\x91\\xbcI\\x00<\\xbd\\x18\\x1a\\xa3<\\xf9J%\\xbc\\n\\xe7\\xbf\\xbbr\\x87\\x12=\\x97\\x1d\\x95=\\x83|\\xfd\\xbc\\xed\\xf1\\xd1\\xbd%z\\x84;\\xcb\\tu=c\\x8ai