From 5f5a2dbb45e729d2d9886ce18620a8ff20774a7e Mon Sep 17 00:00:00 2001 From: Robert Shelton Date: Mon, 28 Apr 2025 15:31:44 -0400 Subject: [PATCH 01/10] wip --- .../vector-search/02_hybrid_search.ipynb | 140 ++-- .../vector-search/04_advanced_queries.ipynb | 685 ++++++++++++++++++ .../vector-search/resources/movies.json | 20 + 3 files changed, 775 insertions(+), 70 deletions(-) create mode 100644 python-recipes/vector-search/04_advanced_queries.ipynb diff --git a/python-recipes/vector-search/02_hybrid_search.ipynb b/python-recipes/vector-search/02_hybrid_search.ipynb index 577d4e52..4dad4a7b 100644 --- a/python-recipes/vector-search/02_hybrid_search.ipynb +++ b/python-recipes/vector-search/02_hybrid_search.ipynb @@ -125,7 +125,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -152,7 +152,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -163,7 +163,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -175,7 +175,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -188,14 +188,14 @@ "movie_data = [\n", " {\n", " **movie,\n", - " \"description_vector\": model.embed(movie[\"description\"], as_buffer=True, dtype=\"float32\")\n", + " \"description_vector\": model.embed(movie[\"description\"], as_buffer=True)\n", " } for movie in movies\n", "]" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -205,10 +205,10 @@ " '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", - " 'description_vector': b'\\x91f|=\\xb6`\\n;g\\x92\\xb7;3\\xcb~\\xbd\\x16e\\xce\\xbb\\xd7\\x16J=P\\xa7?=\\xc8v\\x95\\x17\\xbe\\x02\\x1a\\x05\\xb9@u\\xbf<\\xd6\\xe2b\\xba\\xd0\\xa6\\xa8\\xbdo\\xdc\\xec\\xbcQc%=N\\xe7r\\xbb\\x1dOG==(\\x85=y@\\xa2\\xbc7Z\\xd0\\xbdB%K\\xbd\\xba\\xed\\x94\\xbcU\\xddH=\\xbe&F<\\xbc*\\xec<\\x8c\\xd8\\x8d\\xbd\\xf3Z\\x98<\\x15\\xa3\\xa3=3g3\\xbd$\\xcd\\xbd\\xbd\\xf7$\\xf7;\\xf6\\xf4z=\\x02\\xb5\\x8c=\\x8d\\x0e\\xc6\\xbdhI\\x90\\xbdq\\x16\\xbd;u\\xe7\\x0c\\xbd&3\\xc9\\xbc\\x82\\xf8\\xbb\\xbc\\xa7&u\\xbb-\\x8f\\xca<\\xf2\\x7fJ=\\x14\\xaf*=\\x87OU\\xbd\\xde\\xf0\\x95\\xbc \\x02\\x19=\\x1b\\xf4K<\\xd0\\xc2\\t=F\\x83\\xac=\\x9e\\xd7\\xb8\\xbd\\xf3\\xb5\\x9c\\xbdB\\x85\\x18=\\xa4d&=\\'3\\xf8<\\xd3\\xf7\\x88\\xbd\\x7f\\x1bF\\xbd\\x9f?\\x14\\xbe\\xc9\\x8f(\\xbd\\xe4O\\x89\\xbd\\x18\\xae\\xd4<\\xb2\\x12\\xc3=\\xb0\\x05O\\xbd\\x8f\\x8ep\\xbc\\x1a\\xb5\\xac\\xbc\\xcc\\x9ee\\xbdv\\x8es;\\x0ca\\xc1;\\xd5\\xfaB\\xbde%\\xfe:\\x99\\xe6\\xf4=\\xa7\\x15*<\\x8c\\xf8\\x1b=\\x08\\xfcV\\xbd\\xce\\xd1\\r=<\\xee\\x06=\\x17u\\xba\\xbd\\r\\xa4\\xd6<\\x12\\xec\\xd9;\\xc89/=\\xa6\\xc2\\x85=x\\x0b\"=\\xe3i\\xef<4\\xe8c=\\xfc2\\x08\\xbe\\xd2\\x12;=\\x98VW;N\\xa4b<\\xe8\\x9d\\xb7<\\x90r;\\xbd\\\\z\\x91\\xbcO\\x00<\\xbd\\x13\\x1a\\xa3<\\x05K%\\xbcc\\xe7\\xbf\\xbb\\x89\\x87\\x12=\\x95\\x1d\\x95=||\\xfd\\xbc\\xf2\\xf1\\xd1\\xbdKz\\x84;\\xc7\\tu=.\\x8ai<=\\x91R\\xbd\\xdd\\xf3m\\xbd\\x8c\\xb83=_\\xedF=\\x1a\\xf3\\xd1\\x08oA\\xba<(\\xacO\\xbd\\xfc\\x0e\\xc7;\\x87\\xf4\\x04\\xbdN\\x82\\x92\\xbd\\x92\\xddD=a\\xd8;\\xbc\\xd1;\\xf4\\xbc\\xb2\\x8f\\x97\\xbd<\\\\\\r\\xbd\\xe1\\x8c\\xf5\\xbd\\x95\\x13(=\\xa2\\xc8\\xc6=\\xa9\\xed\\x1a=\\x98\\xa8\\xf8=\\x96\\xc1\\xee\\xbc\\xff.\\x18\\xbb\\xbf~;<\\xd9F\\t\\xbd\\x13\\x08\\x17=\\xa8\\xa5\\x1e=\\x17K\\xcb\\xbd0\\xf7\\x8c\\xbdXb\\xed\\xbb\\xc9[\\x19\\xbcU\\x0c\\x13\\xbcdq\\x83=\\xe9wd\\xbd.\\xc7\\xd1\\xbb~lY\\xbc\\xa2|a=a\\xcf\\xfd\\xbcB\\xa5\\x83\\xbb\\x9fO\\x19\\xbd&\\x02]\\xbd\\xb6\\xeaz=\\xff5\\x9c=1^\\xa9\\xbdi^9\\xbcT\\xe4N\\xbc}\\x07x\\xbd\\x17{\\xa0=@\\x9f\\x96<\\x81s8\\xba\\xa6\\xbb=\\xbd\\xb2|(<\\xc1\\xdf\\xb4\\xbbr\\xc9\\x0b\\xbd\\xc2\\x01\\x95\\xbd\\x02\\xc7T=\\x11p\\xd1\\x0c\\xb1\\xbch\\x01J\\xbda\\xf4~==\\xe3Z\\xbd?/\\xf1\\xbbJ98=\\xd92T\\xbc.\\'\\x81<\\xbd\\xa0M=\\xa0\\xde\\x05<\\x1bI|\\xbd\\xc4\\x98w<\\xdf\\xd3\\xa7\\xbd\\xdbS \\xbdl\\x13\\x07=\\x18&\\x14\\xbc\\xbev\\xe9<\\xfa,\\x97='}]" + " 'description_vector': b'\\x8bf|=\\xc3`\\n;\\xf2\\x91\\xb7;?\\xcb~\\xbd\\xdfd\\xce\\xbb\\xc7\\x16J=H\\xa7?=\\xdfv\\x95\\x17\\xbeA\\x1e\\x05\\xb9Hu\\xbfg3\\xbd$\\xcd\\xbd\\xbd\\xa1$\\xf7;\\x04\\xf5z=\\xfc\\xb4\\x8c=\\x89\\x0e\\xc6\\xbdhI\\x90\\xbd^\\x16\\xbd;z\\xe7\\x0c\\xbd\\x1b3\\xc9\\xbc\\x89\\xf8\\xbb\\xbc\\x18\\'u\\xbb>\\x8f\\xca<\\x02\\x80J=\\x0e\\xaf*=\\x8dOU\\xbd\\xcf\\xf0\\x95\\xbc \\x02\\x19=\\x19\\xf4K<\\xc5\\xc2\\t=J\\x83\\xac=\\x95\\xd7\\xb8\\xbd\\xf2\\xb5\\x9c\\xbd=\\x85\\x18=\\x94d&=03\\xf8<\\xee\\xf7\\x88<\\x80v\\xf2\\xbb9=[\\xbdG\\xac\\xee\\xbb<:A\\xbd\\xe1d\\x19\\xbd!d\\xf2\\xbb\\x1d\\xbax;\\xec;O<\\xd21,\\xbc\\xec\\xae\\xae=r\\x00-\\xbc\"\\x06\\xae\\xbdl\\xd6\\x1a=\\xc4\\xbf\\xcd=\\x19\\x150=\\xe3\\xf1\\x9d\\xbc\\xa6GK=\\xb2\\xb8 =\\xb2\\xf1I\\xbd-e\\x9e\\xbb\\xe9\\x8a\\xf7:\\x88\\xf8\\x1c=\\x7f\\xba\\xde<\\xd2n\\x16\\xbb\\xb4\\\\p\\xbb\\xd4\\xd5<<\\x89\\xa5\\xa3\\xb8\\xc79s<=4&<\\x84\\x1c\\x18<\\x18\\xd9-\\xbd\\xdf\\xe6\\x98<\\x15\\xa1N=\\xa2/\\xa5=\\x1d\\xf3\\xdd<\\x17L\\x13<\\x10\\x10\\xce\\xbac\\x9e\\xdc\\xbc\\xa68\\x05=+\\xa1\\xf5\\xbd\\x84\\x1bF\\xbd\\xa0?\\x14\\xbe\\xc4\\x8f(\\xbd\\xe6O\\x89\\xbd\\xf7\\xad\\xd4<\\xa7\\x12\\xc3=\\xaf\\x05O\\xbd\\x99\\x8ep\\xbc\\x18\\xb5\\xac\\xbc\\xc9\\x9ee\\xbdH\\x8es;$a\\xc1;\\xd9\\xfaB\\xbd\\xa8#\\xfe:\\x92\\xe6\\xf4=\\xcd\\x15*<\\x86\\xf8\\x1b=\\x01\\xfcV\\xbd\\xd3\\xd1\\r=9\\xee\\x06=\\x13u\\xba\\xbd\\xf7\\xa3\\xd6<\\x1a\\xec\\xd9;\\xb79/=\\xa4\\xc2\\x85=p\\x0b\"=\\xe1i\\xef<:\\xe8c=\\xfb2\\x08\\xbe\\xce\\x12;=OVW;V\\xa4b<\\xd0\\x9d\\xb7<\\x87r;\\xbdqz\\x91\\xbcV\\x00<\\xbd\\xfe\\x19\\xa3<\\xeaJ%\\xbc!\\xe7\\xbf\\xbb\\x7f\\x87\\x12=\\x94\\x1d\\x95=b|\\xfd\\xbc\\xf3\\xf1\\xd1\\xbd\\xf5y\\x84;\\xc9\\tu=]\\x8ai<3\\x91R\\xbd\\xec\\xf3m\\xbd\\x93\\xb83=V\\xedF=\\x1f\\xf3\\xd1\\x08yA\\xba<#\\xacO\\xbd\\x01\\x0f\\xc7;\\x7f\\xf4\\x04\\xbdP\\x82\\x92\\xbd\\x9b\\xddD=p\\xd8;\\xbc\\xd3;\\xf4\\xbc\\xb3\\x8f\\x97\\xbd1\\\\\\r\\xbd\\xea\\x8c\\xf5\\xbd\\x8c\\x13(=\\x9e\\xc8\\xc6=\\xa3\\xed\\x1a=\\x98\\xa8\\xf8=\\x84\\xc1\\xee\\xbc\\xcd-\\x18\\xbb\\xf5~;<\\xd6F\\t\\xbd\\x14\\x08\\x17=\\xa5\\xa5\\x1e=\\x14K\\xcb\\xbd.\\xf7\\x8c\\xbdyb\\xed\\xbb\\x86[\\x19\\xbc]\\x0c\\x13\\xbcgq\\x83=\\xf0wd\\xbd\\xe3\\xc7\\xd1\\xbb8lY\\xbc\\xa7|a=3\\xcf\\xfd\\xbc\\x1f\\xa5\\x83\\xbb\\x99O\\x19\\xbd6\\x02]\\xbd\\xbb\\xeaz=\\x036\\x9c=:^\\xa9\\xbd)^9\\xbcg\\xe4N\\xbcs\\x07x\\xbd\\x18{\\xa0=:\\x9f\\x96<\\xecq8\\xba\\x9e\\xbb=\\xbd\\xe4|(<\\x96\\xdf\\xb4\\xbbl\\xc9\\x0b\\xbd\\xc4\\x01\\x95\\xbd\\xf7\\xc6T=\\tp\\xd1 VectorQuery:\n", " \"\"\"Generate a Redis vector query given user query string.\"\"\"\n", - " vector = model.embed(user_query, as_buffer=True, dtype=\"float32\")\n", + " vector = model.embed(user_query, as_buffer=True)\n", " query = VectorQuery(\n", " vector=vector,\n", " vector_field_name=\"description_vector\",\n", @@ -686,7 +686,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -720,7 +720,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -753,7 +753,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -787,7 +787,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -836,7 +836,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -878,7 +878,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -903,7 +903,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -933,7 +933,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -951,7 +951,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -964,7 +964,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -1075,7 +1075,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -1117,7 +1117,7 @@ ], "metadata": { "kernelspec": { - "display_name": "redis-ai-res", + "display_name": "Python 3", "language": "python", "name": "python3" }, @@ -1131,7 +1131,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.13.2" + "version": "3.11.9" } }, "nbformat": 4, diff --git a/python-recipes/vector-search/04_advanced_queries.ipynb b/python-recipes/vector-search/04_advanced_queries.ipynb new file mode 100644 index 00000000..fb76fe7e --- /dev/null +++ b/python-recipes/vector-search/04_advanced_queries.ipynb @@ -0,0 +1,685 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "cbba56a9", + "metadata": {}, + "source": [ + "![Redis](https://redis.io/wp-content/uploads/2024/04/Logotype.svg?auto=webp&quality=85,75&width=120)\n", + "# Advanced queries with Redis\n", + "## Let's Begin!\n", + "\"Open\n" + ] + }, + { + "cell_type": "markdown", + "id": "0b80de6b", + "metadata": {}, + "source": [ + "## Prepare data\n", + "\n", + "In this examples we will load a list of movie objects with the following attributes: `title`, `rating`, `description`, and `genre`. \n", + "\n", + "For the vector part of our vector search we will embed the description so that user's can search for movies that best match what they're looking for.\n", + "\n", + "**If you are running this notebook locally**, FYI you may not need to perform this step at all." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "b966a9b5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cloning into 'temp_repo'...\n", + "remote: Enumerating objects: 204, done.\u001b[K\n", + "remote: Counting objects: 100% (52/52), done.\u001b[K\n", + "remote: Compressing objects: 100% (28/28), done.\u001b[K\n", + "remote: Total 204 (delta 37), reused 24 (delta 24), pack-reused 152\u001b[K\n", + "Receiving objects: 100% (204/204), 9.47 MiB | 10.76 MiB/s, done.\n", + "Resolving deltas: 100% (64/64), done.\n", + "mv: temp_repo/python-recipes/vector-search/resources: No such file or directory\n" + ] + } + ], + "source": [ + "# NBVAL_SKIP\n", + "!git clone https://github.com/redis-developer/redis-ai-resources.git temp_repo\n", + "!mv temp_repo/python-recipes/vector-search/resources .\n", + "!rm -rf temp_repo" + ] + }, + { + "cell_type": "markdown", + "id": "19bdc2a5-2192-4f5f-bd6e-7c956fd0e230", + "metadata": {}, + "source": [ + "## Packages" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c620286e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "%pip install -q redis numpy sentence-transformers" + ] + }, + { + "cell_type": "markdown", + "id": "323aec7f", + "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": "code", + "execution_count": null, + "id": "2cb85a99", + "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", + "id": "7c5dbaaf", + "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`" + ] + }, + { + "cell_type": "markdown", + "id": "1d4499ae", + "metadata": {}, + "source": [ + "### 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": null, + "id": "aefda1d1", + "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\", \"6390\") # 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": "markdown", + "id": "f8c6ef53", + "metadata": {}, + "source": [ + "### Create redis client" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "370c1fcc", + "metadata": {}, + "outputs": [], + "source": [ + "from redis import Redis\n", + "client = Redis.from_url(REDIS_URL)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "458fc773", + "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, + "id": "8d561462", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/justin.cechmanek/.pyenv/versions/3.11.9/envs/redis-ai-res/lib/python3.11/site-packages/sentence_transformers/cross_encoder/CrossEncoder.py:11: TqdmExperimentalWarning: Using `tqdm.autonotebook.tqdm` in notebook mode. Use `tqdm.tqdm` instead to force console mode (e.g. in jupyter console)\n", + " from tqdm.autonotebook import tqdm, trange\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": 6, + "id": "9946a382", + "metadata": {}, + "outputs": [], + "source": [ + "# Note: convert embedding array to bytes for storage in Redis Hash data type\n", + "movie_data = [\n", + " {\n", + " **movie,\n", + " \"vector\": embed_text(model, movie[\"description\"])\n", + " } for movie in movies\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "8797fcc6", + "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'\\x9bf|=\\xa4a\\n;\\xb6\\x91\\xb7;*\\xcb~\\xbd\\x07e\\xce\\xbb\\xc9\\x16J=G\\xa7?=\\xcev\\x95\\x17\\xbe\\xc0 \\x05\\xb9&u\\xbf<0\\xe2b\\xba\\xd6\\xa6\\xa8\\xbdr\\xdc\\xec\\xbcWc%=\\xa6\\xe7r\\xbb\"OG=:(\\x85=s@\\xa2\\xbc/Z\\xd0\\xbdK%K\\xbd\\xb1\\xed\\x94\\xbc`\\xddH=\\xaa&F<\\xe0*\\xec<\\x88\\xd8\\x8d\\xbd\\xc5Z\\x98<\\x13\\xa3\\xa3=:g3\\xbd+\\xcd\\xbd\\xbd\\x90$\\xf7;\\xf8\\xf4z=\\x01\\xb5\\x8c=\\x8a\\x0e\\xc6\\xbdoI\\x90\\xbd\\x80\\x16\\xbd;u\\xe7\\x0c\\xbd\\xf32\\xc9\\xbc\\x8b\\xf8\\xbb\\xbcP&u\\xbb9\\x8f\\xca<\\x07\\x80J=\\x10\\xaf*=\\x96OU\\xbd\\xc9\\xf0\\x95\\xbc\\x10\\x02\\x19=\\x12\\xf4K<\\xc0\\xc2\\t=L\\x83\\xac=\\x98\\xd7\\xb8\\xbd\\xf7\\xb5\\x9c\\xbd9\\x85\\x18=\\x9fd&=73\\xf8<\\xfb\\xf7\\x88<\\xabv\\xf2\\xbb%=[\\xbd\\xdc\\xac\\xee\\xbb2:A\\xbd\\xdcd\\x19\\xbdjd\\xf2\\xbbr\\xbax;\\xdc;O<\\x991,\\xbc\\xea\\xae\\xae=~\\x00-\\xbc\\x1a\\x06\\xae\\xbdh\\xd6\\x1a=\\xc7\\xbf\\xcd=\\x1f\\x150=\\xdc\\xf1\\x9d\\xbc\\xaaGK=\\xaf\\xb8 =\\xb0\\xf1I\\xbd\\te\\x9e\\xbbI\\x8b\\xf7:\\x8b\\xf8\\x1c=\\x86\\xba\\xde<)o\\x16\\xbb\\x19]p\\xbb\\xc3\\xd5<\\xbd\\x86\\x1bF\\xbd\\xa2?\\x14\\xbe\\xc5\\x8f(\\xbd\\xdfO\\x89\\xbd\\x10\\xae\\xd4<\\xa9\\x12\\xc3=\\xad\\x05O\\xbdn\\x8ep\\xbc$\\xb5\\xac\\xbc\\xc5\\x9ee\\xbdf\\x8es;\\xee`\\xc1;\\xd3\\xfaB\\xbdC#\\xfe:\\x90\\xe6\\xf4=\\xba\\x15*;~=@J=\\x19\\x13=$X\\x7f<=ZPm==*\\x023+\\x06ߞ<1\\x1a=6_ٻtJ\\'=Z\\x0e\\'0L=^֣\\n&ed6=m)=dTH=]p=\\x1c}\\'<\\x03\\x1fFu<؛;*q7M={Q5kW\\x1f=\\x1e;k^A=?E\\x04Enw\\x13<\\x1c_S=ӧL\\x05:ջ\\x01jNn=L=\\x14=أv\\x0etV\\x0fALR=<3;ǽH\\x1bhao{=A|r\\x11%&\\x00\\x13Q=\\x05n<\\x1e\\x10=\\x1f\\x1e/\\x05=\\x06\\x0e=n6\\x08s\\x13;F<\\r<\\x02\\x0c<\\x02=\\x00Uм\\x1c;\\x082=sszS=0Լ)\\x01\\x1c\\x00꽻X=<\\x0cq\\n|<<ɽ\\x16\\x1c\\u07bdm2-_=D::8RM(Bq}6=l=[=?W<\\x18=q1h=ĝi<~$\\x01=-8/}L\\x1b\\x1b=G\\x01\\x01<Ƕ\\nW=*X\\x18*s;g^E=)\"=XbX-ɼ8\\x04ټ@k<٥ʽף=$=\\'\\x02M\\x02v;4dU<\\x16\\x1c\\x7f\\x107HV73\\x0f\\x0f>Vh갣!\\x18<#F\\x14ż#\\x03=\\x0c\\x0f;Ymͼ\\x1e\\x1a;}p+\\nah\\x1bqռ$]pʼJ̇#Wk=\\x0e*6څ =קf\\x10\\x13)I

bl<*ĺ0<\\t&̴qI\\x16=P<+[&F\\x06=\\\\V={\\x7f\\x19\\x01\\x0e<2+QF{\\x08Q\\x01<,\\x1b*d\\x01:\\x10D\\x11d=\\rFvT=;/==A9YڽZ1D<3US=MY\\\\=V;=\\x1absZ<\\x1fB=\\x0b[?_=?<:J=<-Ҝ<0<\\t5Zʝ=Z;5<ü[=\\x14лP⼊*\\x11=*N=!FՉ̼\\r;\\x12<\\u05fd\\nԽZ]\\'<%U@\\x174P_@]нF=A<&\\n\\x11v«#+=[閽\\x07f\\x19Kp0\\x08pq;mMꚽR漉\\x17=o\\x00=x?\\x07=I;\\x13.<\\x7fv=\\x150\\x1dP=0\\x05=!>J=\\x04*uچ=@>7ټE佛sV\\x10R\\x1e==P뼙{\\x0b<+^\\x17=[<\\x0eh\\x04\\x02=zӼHm\\n=\\x0e;:\\x1fє<1=|\\x08t5-peҜ:=\\x04˽hlz&=UUB(|5=&=\\x07\\x14/<+.<\\x05e;\\n<=$\\x1f=\\x042\\x03>w<ޖʼ衝=\\x05G=\\x7fR\\x17wql\\x12x%?;\\x04f\\x088b_=r\\x06<\\x1b<$n\\x0e=vs=\\x10\\x15`=\\x16J_Ѣ?\\x12T>=\\x15\\x06=W=37;Q\\t\\x00\\x18=\\x05q=Q;\\'W\\x05=\\x1a=$4=b6=|=!c=I=J<\\\\`ʍ:+<\\u07b5<\\x03<\\x15Xʼ\"e>\\x1cg=DB<\\x0e<\\x1bK\\x11;8ν<1\\n\\x1976{=/\\x05=;]I\\x1cK\\x1aT;_R[8H=:#=(2=\\x1a\\x03>1n=(d;!\\u07b2t<~\"b;*\\x1b/\\x0cT<]λ{\\x0b=Qԅ=ӦF\\x16q\\x18=A\\x17=씼{=\\x0c0\\x03Ѡ<\\'%<_u=z½1x^S\\x0c\\u05fdŗK=\\x17\\x10\\x16\\x1f!\\\\;yFe =-,d=\\x1dx<=QAһE\\x08j/==嶻<ݼN_[0;C<|ihfx懼\\t\\r\\x00w\\x16z\"9\\x11Dd,мTz5d\\x1bdb%<\\x15,\\u05cb[5,\\x0cM=/ μTB9\\x10lۊ=\\x17֨=cǼC=\\x06u=%?=\\\\J|9PF\\x0f\\x03>h\\x18=щ\\x1dq\\x0f=ߣ<\\x03\\x0e=nA<\\x16뻥⼽H8|v\\x15\\x12={<\\x00YEHq;\"1m<ܒžQ<י\\x07+\\x13,j\\x16\"=\\x05>\\rS<-\"g\\x1bc!=}hc`\\x18<}溡O=\\x12\\x04ɼ0/\\x10-\\'ar.Q;=LPE\\t&1-\\x12ν샄<\\'+=b\\x0b\\x08(ݼhe\\x14ԍ>=uz\\x7f69=%\\x02\\x12=Hhx\\x0f\\x01>\\x02:;/;=C<7kfk=\\x19=,=x=<\\x15]0= P=GsݠE=e=ú\\u05fcO#7\\x17=&g4\\r\\x04=(<\\x17-~BD\\x08R=7=Q\\x10\\x14T\\x066Iג<~;G_ý 뽜NWm\\x18F<<ͼ\\nd<Ĩh=Y-K2TG\\x08Vz=\\x0b(:rx=\\x18\\x1d;C\\x15\\t=6\\x14&aL.}\\x17=%S=\\x1b;gһ\\x19>AuA9\\x1f=A\"(\\x00>N;[Z=X\\x1b\\x15\\x12>-h\\x00C=\\x13Z=>aOEB=\\x14C=^R-<=!<-=\\x0c%<<\\x06\" M=\\x7f\\uea3cI<\\x11S\\x1e\\x1eE(qb=@\\x14=\\x05\\x027%mL<⛳=\\x06M|u*<<3iK[KNN 3 @vector $vec_param AS dist]\").sort_by(\"dist\").dialect(2)\n", + "\n", + "res = client.ft(index_name).search(query, query_params = {'vec_param': embedded_user_query})\n", + "\n", + "print_results(res)\n" + ] + }, + { + "cell_type": "markdown", + "id": "ef5e1997", + "metadata": {}, + "source": [ + "### Hybrid filter vector search\n", + "\n", + "Redis allows you to combine filter searches on fields within the index object allowing us to create more specific searches." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "d499dcad", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Top 3 movies: [('Fast & Furious 9', 'action', '6'), ('Mad Max: Fury Road', 'action', '8'), ('Explosive Pursuit', 'action', '7')]\n" + ] + } + ], + "source": [ + "# Search for top 3 movies specifically in the action genre\n", + "\n", + "user_query = \"High tech movies\"\n", + "\n", + "embedded_user_query = embed_text(model, user_query)\n", + "\n", + "# Note: genre is a tag field in our schema so the syntax is @:{ | | ...}\n", + "query = Query(\"(@genre:{action})=>[KNN 3 @vector $vec_param AS dist]\").sort_by('dist').dialect(2)\n", + "\n", + "res = client.ft(index_name).search(query, query_params = {'vec_param': embedded_user_query})\n", + "\n", + "print_results(res)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "f59fff2c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Top 3 movies: [('Mad Max: Fury Road', 'action', '8'), ('Explosive Pursuit', 'action', '7'), ('The Avengers', 'action', '8')]\n" + ] + } + ], + "source": [ + "# Search for top 3 movies specifically in the action genre with ratings at or above a 7\n", + "\n", + "user_query = \"High tech movies\"\n", + "\n", + "embedded_user_query = embed_text(model, user_query)\n", + "\n", + "query = Query(\"(@genre:{action} & (@rating:[7 inf]))=>[KNN 3 @vector $vec_param AS dist]\").sort_by('dist').dialect(2)\n", + "\n", + "res = client.ft(index_name).search(query, query_params = {'vec_param': embedded_user_query})\n", + "\n", + "print_results(res)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "8a493ae0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Top 2 movies: [('Despicable Me', 'comedy', '7'), ('The Dark Knight', 'action', '9')]\n" + ] + } + ], + "source": [ + "# Search with full text search for movies that directly mention \"criminal mastermind\" in the description\n", + "\n", + "user_query = \"High tech movies\"\n", + "\n", + "embedded_user_query = embed_text(model, user_query)\n", + "\n", + "query = Query(\"(@description:(criminal mastermind))=>[KNN 3 @vector $vec_param AS dist]\").sort_by('dist').dialect(2)\n", + "\n", + "res = client.ft(index_name).search(query, query_params = {'vec_param': embedded_user_query})\n", + "\n", + "print_results(res)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "c0d7ab60", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Top 3 movies: [('Despicable Me', 'comedy', '7'), ('The Incredibles', 'comedy', '8'), ('Explosive Pursuit', 'action', '7')]\n" + ] + } + ], + "source": [ + "# Vector search with wild card match\n", + "\n", + "user_query = \"High tech movies\"\n", + "\n", + "embedded_user_query = embed_text(model, user_query)\n", + "\n", + "query = Query(\"(@description:(crim*))=>[KNN 3 @vector $vec_param AS dist]\").sort_by('dist').dialect(2)\n", + "\n", + "res = client.ft(index_name).search(query, query_params = {'vec_param': embedded_user_query})\n", + "\n", + "print_results(res)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "748c15ae", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Top 3 movies: [('The Avengers', 'action', '8'), ('Black Widow', 'action', '7'), ('The Princess Diaries', 'comedy', '6')]\n" + ] + } + ], + "source": [ + "# Vector search with fuzzy match\n", + "\n", + "user_query = \"High tech movies\"\n", + "\n", + "embedded_user_query = embed_text(model, user_query)\n", + "\n", + "# Note: fuzzy match is based on Levenshtein distance. Therefore, \"hero\" might return result for \"her\" as an example.\n", + "# See docs for more info https://redis.io/docs/latest/develop/interact/search-and-query/advanced-concepts/query_syntax/\n", + "query = Query(\"(@description:%hero%)=>[KNN 3 @vector $vec_param AS dist]\").sort_by('dist').dialect(2)\n", + "\n", + "res = client.ft(index_name).search(query, query_params = {'vec_param': embedded_user_query})\n", + "\n", + "print_results(res)" + ] + }, + { + "cell_type": "markdown", + "id": "6bd27cb3", + "metadata": {}, + "source": [ + "## Range queries\n", + "\n", + "Range queries allow you to set a pre defined \"threshold\" for which we want to return documents. This is helpful when you only want documents with a certain distance from the search query." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "cafe1795", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Top 6 movies: [('The Incredibles', 'comedy', '8'), ('Black Widow', 'action', '7'), ('Despicable Me', 'comedy', '7'), ('Shrek', 'comedy', '8'), ('Monsters, Inc.', 'comedy', '8'), ('Aladdin', 'comedy', '8')]\n" + ] + } + ], + "source": [ + "user_query = \"Family friendly fantasy movies\"\n", + "\n", + "embedded_user_query = embed_text(model, user_query)\n", + "\n", + "query = (\n", + " Query(\"@vector:[VECTOR_RANGE $radius $vector]=>{$YIELD_DISTANCE_AS: vector_distance}\")\n", + " .sort_by(\"vector_distance\")\n", + " .return_fields(\"title\", \"rating\", \"genre\", \"vector_distance\")\n", + " .dialect(2)\n", + ")\n", + "\n", + "# Find all vectors within 0.8 of the query vector\n", + "query_params = {\n", + " \"radius\": 0.8,\n", + " \"vector\": embedded_user_query\n", + "}\n", + "\n", + "res = client.ft(index_name).search(query, query_params)\n", + "print_results(res)\n" + ] + }, + { + "cell_type": "markdown", + "id": "a1586ea7", + "metadata": {}, + "source": [ + "Like the queries above, we can also chain additional filters and conditional operators with range queries. The following adds an `or` condition that returns vector search within the defined range or with a rating at or above 9." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "d3110324", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Top 3 movies: [('The Incredibles', 'comedy', '8'), ('The Dark Knight', 'action', '9'), ('Inception', 'action', '9')]\n" + ] + } + ], + "source": [ + "user_query = \"Family friendly fantasy movies\"\n", + "\n", + "embedded_user_query = embed_text(model, user_query)\n", + "\n", + "query = (\n", + " Query(\"@rating:[9 +inf] | @vector:[VECTOR_RANGE $radius $vector]=>{$YIELD_DISTANCE_AS: vector_distance}\")\n", + " .sort_by(\"vector_distance\")\n", + " .return_fields(\"title\", \"rating\", \"genre\", \"vector_distance\")\n", + " .dialect(2)\n", + ")\n", + "\n", + "# Find all vectors within 0.8 of the query vector\n", + "query_params = {\n", + " \"radius\": 0.7,\n", + " \"vector\": embedded_user_query\n", + "}\n", + "\n", + "res = client.ft(index_name).search(query, query_params)\n", + "print_results(res)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "1902b43b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# clean up!\n", + "client.flushall()" + ] + } + ], + "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": 5 +} diff --git a/python-recipes/vector-search/resources/movies.json b/python-recipes/vector-search/resources/movies.json index 57c29d3c..1736f924 100644 --- a/python-recipes/vector-search/resources/movies.json +++ b/python-recipes/vector-search/resources/movies.json @@ -1,119 +1,139 @@ [ { + "id": 1, "title": "Explosive Pursuit", "genre": "action", "rating": 7, "description": "A daring cop chases a notorious criminal across the city in a high-stakes game of cat and mouse." }, { + "id": 2, "title": "Skyfall", "genre": "action", "rating": 8, "description": "James Bond returns to track down a dangerous new enemy who threatens global security." }, { + "id": 3, "title": "Fast & Furious 9", "genre": "action", "rating": 6, "description": "Dom and his crew face off against a high-tech enemy with advanced weapons and technology." }, { + "id": 4, "title": "Black Widow", "genre": "action", "rating": 7, "description": "Natasha Romanoff confronts her dark past and family ties as she battles a new enemy." }, { + "id": 5, "title": "John Wick", "genre": "action", "rating": 8, "description": "A retired hitman seeks vengeance against those who wronged him, leaving a trail of destruction in his wake." }, { + "id": 6, "title": "Mad Max: Fury Road", "genre": "action", "rating": 8, "description": "In a post-apocalyptic wasteland, Max teams up with Furiosa to escape a tyrant's clutches and find freedom." }, { + "id": 7, "title": "The Dark Knight", "genre": "action", "rating": 9, "description": "Batman faces off against the Joker, a criminal mastermind who threatens to plunge Gotham into chaos." }, { + "id": 8, "title": "Gladiator", "genre": "action", "rating": 8, "description": "A betrayed Roman general seeks revenge against the corrupt emperor who murdered his family." }, { + "id": 9, "title": "Inception", "genre": "action", "rating": 9, "description": "A thief who enters dreams to steal secrets faces his toughest mission yet, with reality itself at stake." }, { + "id": 10, "title": "The Avengers", "genre": "action", "rating": 8, "description": "Earth's mightiest heroes come together to stop an alien invasion that threatens the entire planet." }, { + "id": 11, "title": "Toy Story", "genre": "comedy", "rating": 8, "description": "Woody, a good-hearted cowboy doll who belongs to a young boy named Andy, sees his position as Andy's favorite toy jeopardized when his parents buy him a Buzz Lightyear action figure. Even worse, the arrogant Buzz thinks he's a real spaceman on a mission to return to his home planet." }, { + "id": 12, "title": "The Lego Movie", "genre": "comedy", "rating": 7, "description": "An ordinary Lego construction worker, thought to be the prophesied 'Special', is recruited to join a quest to stop an evil tyrant from gluing the Lego universe into eternal stasis." }, { + "id": 13, "title": "Aladdin", "genre": "comedy", "rating": 8, "description": "A kind-hearted street urchin and a power-hungry Grand Vizier vie for a magic lamp that has the power to make their deepest wishes come true." }, { + "id": 14, "title": "Finding Nemo", "genre": "comedy", "rating": 8, "description": "After his son is captured in the Great Barrier Reef and taken to Sydney, a timid clownfish sets out on a journey to bring him home." }, { + "id": 15, "title": "Shrek", "genre": "comedy", "rating": 8, "description": "A mean lord exiles fairytale creatures to the swamp of a grumpy ogre, who must go on a quest and rescue a princess for the lord in order to get his land back." }, { + "id": 16, "title": "The Incredibles", "genre": "comedy", "rating": 8, "description": "A family of undercover superheroes, while trying to live the quiet suburban life, are forced into action to save the world. Bob Parr (Mr. Incredible) and his wife Helen (Elastigirl) were among the world's greatest crime fighters, but now they must assume civilian identities and retreat to the suburbs to live a 'normal' life with their three children. However, the family's desire to help the world pulls them back into action when they face a new and dangerous enemy." }, { + "id": 17, "title": "Monsters, Inc.", "genre": "comedy", "rating": 8, "description": "In order to power the city, monsters have to scare children so that they scream. However, the children are toxic to the monsters, and after a child gets through, two monsters realize things may not be what they think." }, { + "id": 18, "title": "Despicable Me", "genre": "comedy", "rating": 7, "description": "When a criminal mastermind uses a trio of orphan girls as pawns for a grand scheme, he finds their love is profoundly changing him for the better." }, { + "id": 19, "title": "Madagascar", "genre": "comedy", "rating": 7, "description": "A group of animals who have spent all their life in a New York zoo end up in the jungles of Madagascar, and must adjust to living in the wild." }, { + "id": 20, "title": "The Princess Diaries", "genre": "comedy", "rating": 6, From 5d97d2dbaaabfec3c95f3d13d417259dd8342392 Mon Sep 17 00:00:00 2001 From: Robert Shelton Date: Wed, 30 Apr 2025 15:05:57 -0400 Subject: [PATCH 02/10] before meeting --- .../vector-search/04_advanced_queries.ipynb | 338 ++++++++++++------ 1 file changed, 234 insertions(+), 104 deletions(-) diff --git a/python-recipes/vector-search/04_advanced_queries.ipynb b/python-recipes/vector-search/04_advanced_queries.ipynb index fb76fe7e..adb75e09 100644 --- a/python-recipes/vector-search/04_advanced_queries.ipynb +++ b/python-recipes/vector-search/04_advanced_queries.ipynb @@ -135,7 +135,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "id": "aefda1d1", "metadata": {}, "outputs": [], @@ -144,7 +144,7 @@ "\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\", \"6390\") # ex: 18374\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", @@ -161,18 +161,30 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 11, "id": "370c1fcc", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "from redis import Redis\n", - "client = Redis.from_url(REDIS_URL)" + "client = Redis.from_url(REDIS_URL)\n", + "client.ping()" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 10, "id": "458fc773", "metadata": {}, "outputs": [], @@ -185,7 +197,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "id": "8d561462", "metadata": {}, "outputs": [ @@ -193,8 +205,10 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/justin.cechmanek/.pyenv/versions/3.11.9/envs/redis-ai-res/lib/python3.11/site-packages/sentence_transformers/cross_encoder/CrossEncoder.py:11: TqdmExperimentalWarning: Using `tqdm.autonotebook.tqdm` in notebook mode. Use `tqdm.tqdm` instead to force console mode (e.g. in jupyter console)\n", - " from tqdm.autonotebook import tqdm, trange\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", + "/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" ] } ], @@ -211,7 +225,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "id": "9946a382", "metadata": {}, "outputs": [], @@ -227,21 +241,22 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "id": "8797fcc6", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "{'title': 'Explosive Pursuit',\n", + "{'id': 1,\n", + " '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'\\x9bf|=\\xa4a\\n;\\xb6\\x91\\xb7;*\\xcb~\\xbd\\x07e\\xce\\xbb\\xc9\\x16J=G\\xa7?=\\xcev\\x95\\x17\\xbe\\xc0 \\x05\\xb9&u\\xbf<0\\xe2b\\xba\\xd6\\xa6\\xa8\\xbdr\\xdc\\xec\\xbcWc%=\\xa6\\xe7r\\xbb\"OG=:(\\x85=s@\\xa2\\xbc/Z\\xd0\\xbdK%K\\xbd\\xb1\\xed\\x94\\xbc`\\xddH=\\xaa&F<\\xe0*\\xec<\\x88\\xd8\\x8d\\xbd\\xc5Z\\x98<\\x13\\xa3\\xa3=:g3\\xbd+\\xcd\\xbd\\xbd\\x90$\\xf7;\\xf8\\xf4z=\\x01\\xb5\\x8c=\\x8a\\x0e\\xc6\\xbdoI\\x90\\xbd\\x80\\x16\\xbd;u\\xe7\\x0c\\xbd\\xf32\\xc9\\xbc\\x8b\\xf8\\xbb\\xbcP&u\\xbb9\\x8f\\xca<\\x07\\x80J=\\x10\\xaf*=\\x96OU\\xbd\\xc9\\xf0\\x95\\xbc\\x10\\x02\\x19=\\x12\\xf4K<\\xc0\\xc2\\t=L\\x83\\xac=\\x98\\xd7\\xb8\\xbd\\xf7\\xb5\\x9c\\xbd9\\x85\\x18=\\x9fd&=73\\xf8<\\xfb\\xf7\\x88<\\xabv\\xf2\\xbb%=[\\xbd\\xdc\\xac\\xee\\xbb2:A\\xbd\\xdcd\\x19\\xbdjd\\xf2\\xbbr\\xbax;\\xdc;O<\\x991,\\xbc\\xea\\xae\\xae=~\\x00-\\xbc\\x1a\\x06\\xae\\xbdh\\xd6\\x1a=\\xc7\\xbf\\xcd=\\x1f\\x150=\\xdc\\xf1\\x9d\\xbc\\xaaGK=\\xaf\\xb8 =\\xb0\\xf1I\\xbd\\te\\x9e\\xbbI\\x8b\\xf7:\\x8b\\xf8\\x1c=\\x86\\xba\\xde<)o\\x16\\xbb\\x19]p\\xbb\\xc3\\xd5<\\xbd\\x86\\x1bF\\xbd\\xa2?\\x14\\xbe\\xc5\\x8f(\\xbd\\xdfO\\x89\\xbd\\x10\\xae\\xd4<\\xa9\\x12\\xc3=\\xad\\x05O\\xbdn\\x8ep\\xbc$\\xb5\\xac\\xbc\\xc5\\x9ee\\xbdf\\x8es;\\xee`\\xc1;\\xd3\\xfaB\\xbdC#\\xfe:\\x90\\xe6\\xf4=\\xba\\x15*\\x17\\xbeA\\x1e\\x05\\xb9Hu\\xbfg3\\xbd$\\xcd\\xbd\\xbd\\xa1$\\xf7;\\x04\\xf5z=\\xfc\\xb4\\x8c=\\x89\\x0e\\xc6\\xbdhI\\x90\\xbd^\\x16\\xbd;z\\xe7\\x0c\\xbd\\x1b3\\xc9\\xbc\\x89\\xf8\\xbb\\xbc\\x18\\'u\\xbb>\\x8f\\xca<\\x02\\x80J=\\x0e\\xaf*=\\x8dOU\\xbd\\xcf\\xf0\\x95\\xbc \\x02\\x19=\\x19\\xf4K<\\xc5\\xc2\\t=J\\x83\\xac=\\x95\\xd7\\xb8\\xbd\\xf2\\xb5\\x9c\\xbd=\\x85\\x18=\\x94d&=03\\xf8<\\xee\\xf7\\x88<\\x80v\\xf2\\xbb9=[\\xbdG\\xac\\xee\\xbb<:A\\xbd\\xe1d\\x19\\xbd!d\\xf2\\xbb\\x1d\\xbax;\\xec;O<\\xd21,\\xbc\\xec\\xae\\xae=r\\x00-\\xbc\"\\x06\\xae\\xbdl\\xd6\\x1a=\\xc4\\xbf\\xcd=\\x19\\x150=\\xe3\\xf1\\x9d\\xbc\\xa6GK=\\xb2\\xb8 =\\xb2\\xf1I\\xbd-e\\x9e\\xbb\\xe9\\x8a\\xf7:\\x88\\xf8\\x1c=\\x7f\\xba\\xde<\\xd2n\\x16\\xbb\\xb4\\\\p\\xbb\\xd4\\xd5<<\\x89\\xa5\\xa3\\xb8\\xc79s<=4&<\\x84\\x1c\\x18<\\x18\\xd9-\\xbd\\xdf\\xe6\\x98<\\x15\\xa1N=\\xa2/\\xa5=\\x1d\\xf3\\xdd<\\x17L\\x13<\\x10\\x10\\xce\\xbac\\x9e\\xdc\\xbc\\xa68\\x05=+\\xa1\\xf5\\xbd\\x84\\x1bF\\xbd\\xa0?\\x14\\xbe\\xc4\\x8f(\\xbd\\xe6O\\x89\\xbd\\xf7\\xad\\xd4<\\xa7\\x12\\xc3=\\xaf\\x05O\\xbd\\x99\\x8ep\\xbc\\x18\\xb5\\xac\\xbc\\xc9\\x9ee\\xbdH\\x8es;$a\\xc1;\\xd9\\xfaB\\xbd\\xa8#\\xfe:\\x92\\xe6\\xf4=\\xcd\\x15*<\\x86\\xf8\\x1b=\\x01\\xfcV\\xbd\\xd3\\xd1\\r=9\\xee\\x06=\\x13u\\xba\\xbd\\xf7\\xa3\\xd6<\\x1a\\xec\\xd9;\\xb79/=\\xa4\\xc2\\x85=p\\x0b\"=\\xe1i\\xef<:\\xe8c=\\xfb2\\x08\\xbe\\xce\\x12;=OVW;V\\xa4b<\\xd0\\x9d\\xb7<\\x87r;\\xbdqz\\x91\\xbcV\\x00<\\xbd\\xfe\\x19\\xa3<\\xeaJ%\\xbc!\\xe7\\xbf\\xbb\\x7f\\x87\\x12=\\x94\\x1d\\x95=b|\\xfd\\xbc\\xf3\\xf1\\xd1\\xbd\\xf5y\\x84;\\xc9\\tu=]\\x8ai<3\\x91R\\xbd\\xec\\xf3m\\xbd\\x93\\xb83=V\\xedF=\\x1f\\xf3\\xd1\\x08yA\\xba<#\\xacO\\xbd\\x01\\x0f\\xc7;\\x7f\\xf4\\x04\\xbdP\\x82\\x92\\xbd\\x9b\\xddD=p\\xd8;\\xbc\\xd3;\\xf4\\xbc\\xb3\\x8f\\x97\\xbd1\\\\\\r\\xbd\\xea\\x8c\\xf5\\xbd\\x8c\\x13(=\\x9e\\xc8\\xc6=\\xa3\\xed\\x1a=\\x98\\xa8\\xf8=\\x84\\xc1\\xee\\xbc\\xcd-\\x18\\xbb\\xf5~;<\\xd6F\\t\\xbd\\x14\\x08\\x17=\\xa5\\xa5\\x1e=\\x14K\\xcb\\xbd.\\xf7\\x8c\\xbdyb\\xed\\xbb\\x86[\\x19\\xbc]\\x0c\\x13\\xbcgq\\x83=\\xf0wd\\xbd\\xe3\\xc7\\xd1\\xbb8lY\\xbc\\xa7|a=3\\xcf\\xfd\\xbc\\x1f\\xa5\\x83\\xbb\\x99O\\x19\\xbd6\\x02]\\xbd\\xbb\\xeaz=\\x036\\x9c=:^\\xa9\\xbd)^9\\xbcg\\xe4N\\xbcs\\x07x\\xbd\\x18{\\xa0=:\\x9f\\x96<\\xecq8\\xba\\x9e\\xbb=\\xbd\\xe4|(<\\x96\\xdf\\xb4\\xbbl\\xc9\\x0b\\xbd\\xc4\\x01\\x95\\xbd\\xf7\\xc6T=\\tp\\xd1;~=@J=\\x19\\x13=$X\\x7f<=ZPm==*\\x023+\\x06ߞ<1\\x1a=6_ٻtJ\\'=Z\\x0e\\'0L=^֣\\n&ed6=m)=dTH=]p=\\x1c}\\'<\\x03\\x1fFu<؛;*q7M={Q5kW\\x1f=\\x1e;k^A=?E\\x04Enw\\x13<\\x1c_S=ӧL\\x05:ջ\\x01jNn=L=\\x14=أv\\x0etV\\x0fALR=<3;ǽH\\x1bhao{=A|r\\x11%&\\x00\\x13Q=\\x05n<\\x1e\\x10=\\x1f\\x1e/\\x05=\\x06\\x0e=n6\\x08s\\x13;F<\\r<\\x02\\x0c<\\x02=\\x00Uм\\x1c;\\x082=sszS=0Լ)\\x01\\x1c\\x00꽻X=<\\x0cq\\n|<<ɽ\\x16\\x1c\\u07bdm2-_=D::8RM(Bq}6=l=[=?W<\\x18=q1h=ĝi<~$\\x01=-8/}L\\x1b\\x1b=G\\x01\\x01<Ƕ\\nW=*X\\x18*s;g^E=)\"=XbX-ɼ8\\x04ټ@k<٥ʽף=$=\\'\\x02M\\x02v;4dU<\\x16\\x1c\\x7f\\x107HV73\\x0f\\x0f>Vh갣!\\x18<#F\\x14ż#\\x03=\\x0c\\x0f;Ymͼ\\x1e\\x1a;}p+\\nah\\x1bqռ$]pʼJ̇#Wk=\\x0e*6څ =קf\\x10\\x13)I

bl<*ĺ0<\\t&̴qI\\x16=P<+[&F\\x06=\\\\V={\\x7f\\x19\\x01\\x0e<2+QF{\\x08Q\\x01<,\\x1b*d\\x01:\\x10D\\x11d=\\rFvT=;/==A9YڽZ1D<3US=MY\\\\=V;=\\x1absZ<\\x1fB=\\x0b[?_=?<:J=<-Ҝ<0<\\t5Zʝ=Z;5<ü[=\\x14лP⼊*\\x11=*N=!FՉ̼\\r;\\x12<\\u05fd\\nԽZ]\\'<%U@\\x174P_@]нF=A<&\\n\\x11v«#+=[閽\\x07f\\x19Kp0\\x08pq;mMꚽR漉\\x17=o\\x00=x?\\x07=I;\\x13.<\\x7fv=\\x150\\x1dP=0\\x05=!>J=\\x04*uچ=@>7ټE佛sV\\x10R\\x1e==P뼙{\\x0b<+^\\x17=[<\\x0eh\\x04\\x02=zӼHm\\n=\\x0e;:\\x1fє<1=|\\x08t5-peҜ:=\\x04˽hlz&=UUB(|5=&=\\x07\\x14/<+.<\\x05e;\\n<=$\\x1f=\\x042\\x03>w<ޖʼ衝=\\x05G=\\x7fR\\x17wql\\x12x%?;\\x04f\\x088b_=r\\x06<\\x1b<$n\\x0e=vs=\\x10\\x15`=\\x16J_Ѣ?\\x12T>=\\x15\\x06=W=37;Q\\t\\x00\\x18=\\x05q=Q;\\'W\\x05=\\x1a=$4=b6=|=!c=I=J<\\\\`ʍ:+<\\u07b5<\\x03<\\x15Xʼ\"e>\\x1cg=DB<\\x0e<\\x1bK\\x11;8ν<1\\n\\x1976{=/\\x05=;]I\\x1cK\\x1aT;_R[8H=:#=(2=\\x1a\\x03>1n=(d;!\\u07b2t<~\"b;*\\x1b/\\x0cT<]λ{\\x0b=Qԅ=ӦF\\x16q\\x18=A\\x17=씼{=\\x0c0\\x03Ѡ<\\'%<_u=z½1x^S\\x0c\\u05fdŗK=\\x17\\x10\\x16\\x1f!\\\\;yFe =-,d=\\x1dx<=QAһE\\x08j/==嶻<ݼN_[0;C<|ihfx懼\\t\\r\\x00w\\x16z\"9\\x11Dd,мTz5d\\x1bdb%<\\x15,\\u05cb[5,\\x0cM=/ μTB9\\x10lۊ=\\x17֨=cǼC=\\x06u=%?=\\\\J|9PF\\x0f\\x03>h\\x18=щ\\x1dq\\x0f=ߣ<\\x03\\x0e=nA<\\x16뻥⼽H8|v\\x15\\x12={<\\x00YEHq;\"1m<ܒžQ<י\\x07+\\x13,j\\x16\"=\\x05>\\rS<-\"g\\x1bc!=}hc`\\x18<}溡O=\\x12\\x04ɼ0/\\x10-\\'ar.Q;=LPE\\t&1-\\x12ν샄<\\'+=b\\x0b\\x08(ݼhe\\x14ԍ>=uz\\x7f69=%\\x02\\x12=Hhx\\x0f\\x01>\\x02:;/;=C<7kfk=\\x19=,=x=<\\x15]0= P=GsݠE=e=ú\\u05fcO#7\\x17=&g4\\r\\x04=(<\\x17-~BD\\x08R=7=Q\\x10\\x14T\\x066Iג<~;G_ý 뽜NWm\\x18F<<ͼ\\nd<Ĩh=Y-K2TG\\x08Vz=\\x0b(:rx=\\x18\\x1d;C\\x15\\t=6\\x14&aL.}\\x17=%S=\\x1b;gһ\\x19>AuA9\\x1f=A\"(\\x00>N;[Z=X\\x1b\\x15\\x12>-h\\x00C=\\x13Z=>aOEB=\\x14C=^R-<=!<-=\\x0c%<<\\x06\" M=\\x7f\\uea3cI<\\x11S\\x1e\\x1eE(qb=@\\x14=\\x05\\x027%mL<⛳=\\x06M|u*<<3iK[KNN 3 @vector $vec_param AS dist]\").sort_by(\"dist\").dialect(2)\n", - "\n", - "res = client.ft(index_name).search(query, query_params = {'vec_param': embedded_user_query})\n", + "user_query = \"Depicable me\"\n", "\n", - "print_results(res)\n" + "client.ft(index_name).config_set(\"DEFAULT_DIALECT\", 2)\n", + "res = client.ft(index_name).spellcheck(user_query)\n", + "res\n" ] }, { @@ -400,152 +424,258 @@ "id": "ef5e1997", "metadata": {}, "source": [ - "### Hybrid filter vector search\n", + "## Scenario 2:\n", + "\n", + "1) Query a cluster\n", + "\n", + "2) limit the number of results(rows)\n", + "\n", + "3) Ability to query certain type of document(fq=type:Field1)\n", + "\n", + "4) Return only specific fields in the response (fl=id,type,key,value,score).\n", "\n", - "Redis allows you to combine filter searches on fields within the index object allowing us to create more specific searches." + "Examples:\n", + "\n", + "Note: In redis the most similar concept to a cluster would be an index.\n", + "\n", + "- qt=/clustername&q=example question&rows=10\n", + "- qt=/search&group.limit=500&fl=id,type,key,value,score&q=sample query&fq=type:Field1" ] }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 51, "id": "d499dcad", "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Top 3 movies: [('Fast & Furious 9', 'action', '6'), ('Mad Max: Fury Road', 'action', '8'), ('Explosive Pursuit', 'action', '7')]\n" - ] + "data": { + "text/plain": [ + "[Document {'id': '6', 'payload': None, 'score': 6.267822483123378, 'title': 'The Dark Knight', 'genre': 'action', 'rating': '9', 'description': 'Batman faces off against the Joker, a criminal mastermind who threatens to plunge Gotham into chaos.'},\n", + " Document {'id': '17', 'payload': None, 'score': 5.846220066150412, 'title': 'Despicable Me', 'genre': 'comedy', 'rating': '7', 'description': 'When a criminal mastermind uses a trio of orphan girls as pawns for a grand scheme, he finds their love is profoundly changing him for the better.'}]" + ] + }, + "execution_count": 51, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "# Search for top 3 movies specifically in the action genre\n", + "index_name = \"movies\" # variable\n", "\n", - "user_query = \"High tech movies\"\n", + "# fuzzy search\n", + "user_query = Query(\"Criminal mastermind\")\\\n", + " .scorer(\"BM25STD\") \\\n", + " .with_scores() \\\n", + " .return_fields(\"title\", \"genre\", \"rating\", \"description\") \\\n", + " .paging(0, 10) # limits the amount of results to 10\n", "\n", - "embedded_user_query = embed_text(model, user_query)\n", - "\n", - "# Note: genre is a tag field in our schema so the syntax is @:{ | | ...}\n", - "query = Query(\"(@genre:{action})=>[KNN 3 @vector $vec_param AS dist]\").sort_by('dist').dialect(2)\n", + "res = client.ft(index_name).search(user_query)\n", + "res.docs" + ] + }, + { + "cell_type": "markdown", + "id": "7d916ed1", + "metadata": {}, + "source": [ + "## Scenario 3: Ability to query by adding a weight. \n", "\n", - "res = client.ft(index_name).search(query, query_params = {'vec_param': embedded_user_query})\n", + "Field 1 should have twice the weight compared to field 2.\n", "\n", - "print_results(res)" + "q=field1:(\"sample data value 1\")^2+field2:(\"sample data value 2\")" ] }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "id": "f59fff2c", "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Top 3 movies: [('Mad Max: Fury Road', 'action', '8'), ('Explosive Pursuit', 'action', '7'), ('The Avengers', 'action', '8')]\n" - ] + "data": { + "text/plain": [ + "[Document {'id': '9', 'payload': None, 'title': 'The Avengers', 'genre': 'action', 'rating': '8', 'description': \"Earth's mightiest heroes come together to stop an alien invasion that threatens the entire planet.\"},\n", + " Document {'id': '2', 'payload': None, 'title': 'Fast & Furious 9', 'genre': 'action', 'rating': '6', 'description': 'Dom and his crew face off against a high-tech enemy with advanced weapons and technology.'},\n", + " Document {'id': '0', 'payload': None, 'title': 'Explosive Pursuit', 'genre': 'action', 'rating': '7', 'description': 'A daring cop chases a notorious criminal across the city in a high-stakes game of cat and mouse.'}]" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ "# Search for top 3 movies specifically in the action genre with ratings at or above a 7\n", + "user_query1 = \"High tech\"\n", + "user_query2 = \"heroes villains\"\n", "\n", - "user_query = \"High tech movies\"\n", + "def tokenize(query):\n", + " return \" | \".join(query.split(\" \")).lower()\n", "\n", - "embedded_user_query = embed_text(model, user_query)\n", + "query = Query(f'((@description:({tokenize(user_query1)})=>{{$weight: 1}}) | (@description:({tokenize(user_query2)})=>{{$weight: 10}}))') \\\n", + " .return_fields(\"title\", \"genre\", \"rating\", \"description\") \\\n", + " .dialect(2)\n", "\n", - "query = Query(\"(@genre:{action} & (@rating:[7 inf]))=>[KNN 3 @vector $vec_param AS dist]\").sort_by('dist').dialect(2)\n", + "res = client.ft(index_name).search(query)\n", + "res.docs" + ] + }, + { + "cell_type": "markdown", + "id": "4f308e8d", + "metadata": {}, + "source": [ + "## Scenario 4: Ability to have logical operations\n", "\n", - "res = client.ft(index_name).search(query, query_params = {'vec_param': embedded_user_query})\n", + "q=field1:(\"sample data value 1\")^ || field2:(\"sample data value 2\")\n", "\n", - "print_results(res)" + "q=field1:(\"sample data value 1\")^ && field2:(\"sample data value 2\")" ] }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 48, "id": "8a493ae0", "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Top 2 movies: [('Despicable Me', 'comedy', '7'), ('The Dark Knight', 'action', '9')]\n" - ] + "data": { + "text/plain": [ + "[Document {'id': '9', 'payload': None, 'title': 'The Avengers', 'genre': 'action', 'rating': '8', 'description': \"Earth's mightiest heroes come together to stop an alien invasion that threatens the entire planet.\"},\n", + " Document {'id': '0', 'payload': None, 'title': 'Explosive Pursuit', 'genre': 'action', 'rating': '7', 'description': 'A daring cop chases a notorious criminal across the city in a high-stakes game of cat and mouse.'}]" + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ "# Search with full text search for movies that directly mention \"criminal mastermind\" in the description\n", "\n", - "user_query = \"High tech movies\"\n", + "user_query1 = \"High tech\"\n", + "user_query2 = \"heroes villains\"\n", "\n", - "embedded_user_query = embed_text(model, user_query)\n", + "def tokenize(query):\n", + " return \" | \".join(query.split(\" \")).lower()\n", "\n", - "query = Query(\"(@description:(criminal mastermind))=>[KNN 3 @vector $vec_param AS dist]\").sort_by('dist').dialect(2)\n", + "query = Query(f'((@rating:[7, inf+]) & (@description:({tokenize(user_query1)})=>{{$weight: 1}}) | (@description:({tokenize(user_query2)})=>{{$weight: 10}}))') \\\n", + " .return_fields(\"title\", \"genre\", \"rating\", \"description\") \\\n", + " .dialect(2)\n", "\n", - "res = client.ft(index_name).search(query, query_params = {'vec_param': embedded_user_query})\n", + "res = client.ft(index_name).search(query)\n", + "res.docs" + ] + }, + { + "cell_type": "markdown", + "id": "1f73c402", + "metadata": {}, + "source": [ + "## Scenario 5: Ability to specific type of algorithm.   \n", "\n", - "print_results(res)" + "q=field1:(\"sample data value 1\")^ && field2:(\"sample data value 2\")&defType=edismax " ] }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 59, "id": "c0d7ab60", "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Top 3 movies: [('Despicable Me', 'comedy', '7'), ('The Incredibles', 'comedy', '8'), ('Explosive Pursuit', 'action', '7')]\n" - ] + "data": { + "text/plain": [ + "[Document {'id': '9', 'payload': None, 'score': 4.0, 'title': 'The Avengers', 'genre': 'action', 'rating': '8', 'description': \"Earth's mightiest heroes come together to stop an alien invasion that threatens the entire planet.\"},\n", + " Document {'id': '10', 'payload': None, 'score': 1.3333333333333333, 'title': 'Toy Story', 'genre': 'comedy', 'rating': '8', 'description': \"Woody, a good-hearted cowboy doll who belongs to a young boy named Andy, sees his position as Andy's favorite toy jeopardized when his parents buy him a Buzz Lightyear action figure. Even worse, the arrogant Buzz thinks he's a real spaceman on a mission to return to his home planet.\"}]" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "# Vector search with wild card match\n", + "index_name = \"movies\" # variable\n", "\n", - "user_query = \"High tech movies\"\n", + "user_query = \"cowboys and aliens\"\n", "\n", - "embedded_user_query = embed_text(model, user_query)\n", + "user_query = Query(tokenize(user_query)) \\\n", + " .scorer(\"TFIDF\") \\\n", + " .with_scores() \\\n", + " .return_fields(\"title\", \"genre\", \"rating\", \"description\") \\\n", + " .paging(0, 10) # limits the amount of results to 10\n", + "\n", + "res = client.ft(index_name).search(user_query)\n", + "res.docs" + ] + }, + { + "cell_type": "markdown", + "id": "610f006f", + "metadata": {}, + "source": [ + "## Scenario 6: Ability to query certain type of document which value greater than certain number\n", "\n", - "query = Query(\"(@description:(crim*))=>[KNN 3 @vector $vec_param AS dist]\").sort_by('dist').dialect(2)\n", + "q=field1:(\"sample data value 1\")^ && field2:(\"sample data value 2\")&fq=field3:[50+TO+*] \n", "\n", - "res = client.ft(index_name).search(query, query_params = {'vec_param': embedded_user_query})\n", + "=> shown with ratings with scenario 4" + ] + }, + { + "cell_type": "markdown", + "id": "1ce1601d", + "metadata": {}, + "source": [ + "## Scenario 7: Ability to return score for each document.\n", "\n", - "print_results(res)" + "=> scores return shown in other examples" + ] + }, + { + "cell_type": "markdown", + "id": "4d83434b", + "metadata": {}, + "source": [ + "## Scenario 8: vector search\n", + "\n", + "Beyond the capabilities shown here for feature parody, redis offers vector search which can combined with all the methods above to facilitate more powerful queries. Implementing vector search is very easy (especially with the [redis vector library](https://github.com/redis/redis-vl-python)). \n", + "\n", + "In the following example you can see how event thought the word **sentimental** doesn't show up anywhere in the corpus we're still able to effectively find movies that match the semantic meaning of that word." ] }, { "cell_type": "code", - "execution_count": 17, - "id": "748c15ae", + "execution_count": 64, + "id": "09c55f39", "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Top 3 movies: [('The Avengers', 'action', '8'), ('Black Widow', 'action', '7'), ('The Princess Diaries', 'comedy', '6')]\n" - ] + "data": { + "text/plain": [ + "[Document {'id': '17', 'payload': None, 'title': 'Despicable Me', 'genre': 'comedy', 'rating': '7', 'description': 'When a criminal mastermind uses a trio of orphan girls as pawns for a grand scheme, he finds their love is profoundly changing him for the better.'},\n", + " Document {'id': '3', 'payload': None, 'title': 'Black Widow', 'genre': 'action', 'rating': '7', 'description': 'Natasha Romanoff confronts her dark past and family ties as she battles a new enemy.'},\n", + " Document {'id': '15', 'payload': None, 'title': 'The Incredibles', 'genre': 'comedy', 'rating': '8', 'description': \"A family of undercover superheroes, while trying to live the quiet suburban life, are forced into action to save the world. Bob Parr (Mr. Incredible) and his wife Helen (Elastigirl) were among the world's greatest crime fighters, but now they must assume civilian identities and retreat to the suburbs to live a 'normal' life with their three children. However, the family's desire to help the world pulls them back into action when they face a new and dangerous enemy.\"}]" + ] + }, + "execution_count": 64, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "# Vector search with fuzzy match\n", + "from redis.commands.search.query import Query\n", "\n", - "user_query = \"High tech movies\"\n", + "user_query = \"Sentimental movies\"\n", "\n", "embedded_user_query = embed_text(model, user_query)\n", "\n", - "# Note: fuzzy match is based on Levenshtein distance. Therefore, \"hero\" might return result for \"her\" as an example.\n", - "# See docs for more info https://redis.io/docs/latest/develop/interact/search-and-query/advanced-concepts/query_syntax/\n", - "query = Query(\"(@description:%hero%)=>[KNN 3 @vector $vec_param AS dist]\").sort_by('dist').dialect(2)\n", + "# Note: dialect 2 and above required for vector search\n", + "query = Query(\"(*)=>[KNN 3 @vector $vec_param AS dist]\").sort_by(\"dist\").dialect(2).return_fields(\"title\", \"genre\", \"rating\", \"description\").paging(0, 3)\n", "\n", "res = client.ft(index_name).search(query, query_params = {'vec_param': embedded_user_query})\n", - "\n", - "print_results(res)" + "res.docs" ] }, { @@ -560,7 +690,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 65, "id": "cafe1795", "metadata": {}, "outputs": [ @@ -604,7 +734,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 66, "id": "d3110324", "metadata": {}, "outputs": [ From 1689a32c80f6e4b16fddecb675068f41dd981a13 Mon Sep 17 00:00:00 2001 From: Robert Shelton Date: Wed, 30 Apr 2025 19:06:04 -0400 Subject: [PATCH 03/10] wip --- python-recipes/vector-search/04_advanced_queries.ipynb | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/python-recipes/vector-search/04_advanced_queries.ipynb b/python-recipes/vector-search/04_advanced_queries.ipynb index adb75e09..85025094 100644 --- a/python-recipes/vector-search/04_advanced_queries.ipynb +++ b/python-recipes/vector-search/04_advanced_queries.ipynb @@ -372,12 +372,6 @@ "len(res.docs)" ] }, - { - "cell_type": "markdown", - "id": "87ba1dfd", - "metadata": {}, - "source": [] - }, { "cell_type": "markdown", "id": "1488c088", @@ -535,7 +529,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": null, "id": "8a493ae0", "metadata": {}, "outputs": [ From f967965e06cdc8b5eb66d4b528d5dfab9c96f63d Mon Sep 17 00:00:00 2001 From: Robert Shelton Date: Thu, 1 May 2025 11:19:50 -0400 Subject: [PATCH 04/10] add a couple small examples --- python-recipes/vector-search/00_redispy.ipynb | 152 +++- .../vector-search/04_advanced_queries.ipynb | 809 ------------------ 2 files changed, 133 insertions(+), 828 deletions(-) delete mode 100644 python-recipes/vector-search/04_advanced_queries.ipynb diff --git a/python-recipes/vector-search/00_redispy.ipynb b/python-recipes/vector-search/00_redispy.ipynb index ae1c19b2..0766bd5f 100644 --- a/python-recipes/vector-search/00_redispy.ipynb +++ b/python-recipes/vector-search/00_redispy.ipynb @@ -135,7 +135,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "id": "aefda1d1", "metadata": {}, "outputs": [], @@ -161,18 +161,30 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "id": "370c1fcc", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "from redis import Redis\n", - "client = Redis.from_url(REDIS_URL)" + "client = Redis.from_url(REDIS_URL)\n", + "client.ping()" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "id": "458fc773", "metadata": {}, "outputs": [], @@ -185,7 +197,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "id": "8d561462", "metadata": {}, "outputs": [ @@ -193,8 +205,10 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/justin.cechmanek/.pyenv/versions/3.11.9/envs/redis-ai-res/lib/python3.11/site-packages/sentence_transformers/cross_encoder/CrossEncoder.py:11: TqdmExperimentalWarning: Using `tqdm.autonotebook.tqdm` in notebook mode. Use `tqdm.tqdm` instead to force console mode (e.g. in jupyter console)\n", - " from tqdm.autonotebook import tqdm, trange\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", + "/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" ] } ], @@ -211,7 +225,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "id": "9946a382", "metadata": {}, "outputs": [], @@ -227,21 +241,22 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "id": "8797fcc6", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "{'title': 'Explosive Pursuit',\n", + "{'id': 1,\n", + " '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'\\x9bf|=\\xa4a\\n;\\xb6\\x91\\xb7;*\\xcb~\\xbd\\x07e\\xce\\xbb\\xc9\\x16J=G\\xa7?=\\xcev\\x95\\x17\\xbe\\xc0 \\x05\\xb9&u\\xbf<0\\xe2b\\xba\\xd6\\xa6\\xa8\\xbdr\\xdc\\xec\\xbcWc%=\\xa6\\xe7r\\xbb\"OG=:(\\x85=s@\\xa2\\xbc/Z\\xd0\\xbdK%K\\xbd\\xb1\\xed\\x94\\xbc`\\xddH=\\xaa&F<\\xe0*\\xec<\\x88\\xd8\\x8d\\xbd\\xc5Z\\x98<\\x13\\xa3\\xa3=:g3\\xbd+\\xcd\\xbd\\xbd\\x90$\\xf7;\\xf8\\xf4z=\\x01\\xb5\\x8c=\\x8a\\x0e\\xc6\\xbdoI\\x90\\xbd\\x80\\x16\\xbd;u\\xe7\\x0c\\xbd\\xf32\\xc9\\xbc\\x8b\\xf8\\xbb\\xbcP&u\\xbb9\\x8f\\xca<\\x07\\x80J=\\x10\\xaf*=\\x96OU\\xbd\\xc9\\xf0\\x95\\xbc\\x10\\x02\\x19=\\x12\\xf4K<\\xc0\\xc2\\t=L\\x83\\xac=\\x98\\xd7\\xb8\\xbd\\xf7\\xb5\\x9c\\xbd9\\x85\\x18=\\x9fd&=73\\xf8<\\xfb\\xf7\\x88<\\xabv\\xf2\\xbb%=[\\xbd\\xdc\\xac\\xee\\xbb2:A\\xbd\\xdcd\\x19\\xbdjd\\xf2\\xbbr\\xbax;\\xdc;O<\\x991,\\xbc\\xea\\xae\\xae=~\\x00-\\xbc\\x1a\\x06\\xae\\xbdh\\xd6\\x1a=\\xc7\\xbf\\xcd=\\x1f\\x150=\\xdc\\xf1\\x9d\\xbc\\xaaGK=\\xaf\\xb8 =\\xb0\\xf1I\\xbd\\te\\x9e\\xbbI\\x8b\\xf7:\\x8b\\xf8\\x1c=\\x86\\xba\\xde<)o\\x16\\xbb\\x19]p\\xbb\\xc3\\xd5<\\xbd\\x86\\x1bF\\xbd\\xa2?\\x14\\xbe\\xc5\\x8f(\\xbd\\xdfO\\x89\\xbd\\x10\\xae\\xd4<\\xa9\\x12\\xc3=\\xad\\x05O\\xbdn\\x8ep\\xbc$\\xb5\\xac\\xbc\\xc5\\x9ee\\xbdf\\x8es;\\xee`\\xc1;\\xd3\\xfaB\\xbdC#\\xfe:\\x90\\xe6\\xf4=\\xba\\x15*\\x17\\xbeA\\x1e\\x05\\xb9Hu\\xbfg3\\xbd$\\xcd\\xbd\\xbd\\xa1$\\xf7;\\x04\\xf5z=\\xfc\\xb4\\x8c=\\x89\\x0e\\xc6\\xbdhI\\x90\\xbd^\\x16\\xbd;z\\xe7\\x0c\\xbd\\x1b3\\xc9\\xbc\\x89\\xf8\\xbb\\xbc\\x18\\'u\\xbb>\\x8f\\xca<\\x02\\x80J=\\x0e\\xaf*=\\x8dOU\\xbd\\xcf\\xf0\\x95\\xbc \\x02\\x19=\\x19\\xf4K<\\xc5\\xc2\\t=J\\x83\\xac=\\x95\\xd7\\xb8\\xbd\\xf2\\xb5\\x9c\\xbd=\\x85\\x18=\\x94d&=03\\xf8<\\xee\\xf7\\x88<\\x80v\\xf2\\xbb9=[\\xbdG\\xac\\xee\\xbb<:A\\xbd\\xe1d\\x19\\xbd!d\\xf2\\xbb\\x1d\\xbax;\\xec;O<\\xd21,\\xbc\\xec\\xae\\xae=r\\x00-\\xbc\"\\x06\\xae\\xbdl\\xd6\\x1a=\\xc4\\xbf\\xcd=\\x19\\x150=\\xe3\\xf1\\x9d\\xbc\\xa6GK=\\xb2\\xb8 =\\xb2\\xf1I\\xbd-e\\x9e\\xbb\\xe9\\x8a\\xf7:\\x88\\xf8\\x1c=\\x7f\\xba\\xde<\\xd2n\\x16\\xbb\\xb4\\\\p\\xbb\\xd4\\xd5<<\\x89\\xa5\\xa3\\xb8\\xc79s<=4&<\\x84\\x1c\\x18<\\x18\\xd9-\\xbd\\xdf\\xe6\\x98<\\x15\\xa1N=\\xa2/\\xa5=\\x1d\\xf3\\xdd<\\x17L\\x13<\\x10\\x10\\xce\\xbac\\x9e\\xdc\\xbc\\xa68\\x05=+\\xa1\\xf5\\xbd\\x84\\x1bF\\xbd\\xa0?\\x14\\xbe\\xc4\\x8f(\\xbd\\xe6O\\x89\\xbd\\xf7\\xad\\xd4<\\xa7\\x12\\xc3=\\xaf\\x05O\\xbd\\x99\\x8ep\\xbc\\x18\\xb5\\xac\\xbc\\xc9\\x9ee\\xbdH\\x8es;$a\\xc1;\\xd9\\xfaB\\xbd\\xa8#\\xfe:\\x92\\xe6\\xf4=\\xcd\\x15*<\\x86\\xf8\\x1b=\\x01\\xfcV\\xbd\\xd3\\xd1\\r=9\\xee\\x06=\\x13u\\xba\\xbd\\xf7\\xa3\\xd6<\\x1a\\xec\\xd9;\\xb79/=\\xa4\\xc2\\x85=p\\x0b\"=\\xe1i\\xef<:\\xe8c=\\xfb2\\x08\\xbe\\xce\\x12;=OVW;V\\xa4b<\\xd0\\x9d\\xb7<\\x87r;\\xbdqz\\x91\\xbcV\\x00<\\xbd\\xfe\\x19\\xa3<\\xeaJ%\\xbc!\\xe7\\xbf\\xbb\\x7f\\x87\\x12=\\x94\\x1d\\x95=b|\\xfd\\xbc\\xf3\\xf1\\xd1\\xbd\\xf5y\\x84;\\xc9\\tu=]\\x8ai<3\\x91R\\xbd\\xec\\xf3m\\xbd\\x93\\xb83=V\\xedF=\\x1f\\xf3\\xd1\\x08yA\\xba<#\\xacO\\xbd\\x01\\x0f\\xc7;\\x7f\\xf4\\x04\\xbdP\\x82\\x92\\xbd\\x9b\\xddD=p\\xd8;\\xbc\\xd3;\\xf4\\xbc\\xb3\\x8f\\x97\\xbd1\\\\\\r\\xbd\\xea\\x8c\\xf5\\xbd\\x8c\\x13(=\\x9e\\xc8\\xc6=\\xa3\\xed\\x1a=\\x98\\xa8\\xf8=\\x84\\xc1\\xee\\xbc\\xcd-\\x18\\xbb\\xf5~;<\\xd6F\\t\\xbd\\x14\\x08\\x17=\\xa5\\xa5\\x1e=\\x14K\\xcb\\xbd.\\xf7\\x8c\\xbdyb\\xed\\xbb\\x86[\\x19\\xbc]\\x0c\\x13\\xbcgq\\x83=\\xf0wd\\xbd\\xe3\\xc7\\xd1\\xbb8lY\\xbc\\xa7|a=3\\xcf\\xfd\\xbc\\x1f\\xa5\\x83\\xbb\\x99O\\x19\\xbd6\\x02]\\xbd\\xbb\\xeaz=\\x036\\x9c=:^\\xa9\\xbd)^9\\xbcg\\xe4N\\xbcs\\x07x\\xbd\\x18{\\xa0=:\\x9f\\x96<\\xecq8\\xba\\x9e\\xbb=\\xbd\\xe4|(<\\x96\\xdf\\xb4\\xbbl\\xc9\\x0b\\xbd\\xc4\\x01\\x95\\xbd\\xf7\\xc6T=\\tp\\xd1;~=@J=\\x19\\x13=$X\\x7f<=ZPm==*\\x023+\\x06ߞ<1\\x1a=6_ٻtJ\\'=Z\\x0e\\'0L=^֣\\n&ed6=m)=dTH=]p=\\x1c}\\'<\\x03\\x1fFu<؛;*q7M={Q5kW\\x1f=\\x1e;k^A=?E\\x04Enw\\x13<\\x1c_S=ӧL\\x05:ջ\\x01jNn=L=\\x14=أv\\x0etV\\x0fALR=<3;ǽH\\x1bhao{=A|r\\x11%&\\x00\\x13Q=\\x05n<\\x1e\\x10=\\x1f\\x1e/\\x05=\\x06\\x0e=n6\\x08s\\x13;F<\\r<\\x02\\x0c<\\x02=\\x00Uм\\x1c;\\x082=sszS=0Լ)\\x01\\x1c\\x00꽻X=<\\x0cq\\n|<<ɽ\\x16\\x1c\\u07bdm2-_=D::8RM(Bq}6=l=[=?W<\\x18=q1h=ĝi<~$\\x01=-8/}L\\x1b\\x1b=G\\x01\\x01<Ƕ\\nW=*X\\x18*s;g^E=)\"=XbX-ɼ8\\x04ټ@k<٥ʽף=$=\\'\\x02M\\x02v;4dU<\\x16\\x1c\\x7f\\x107HV73\\x0f\\x0f>Vh갣!\\x18<#F\\x14ż#\\x03=\\x0c\\x0f;Ymͼ\\x1e\\x1a;}p+\\nah\\x1bqռ$]pʼJ̇#Wk=\\x0e*6څ =קf\\x10\\x13)I

bl<*ĺ0<\\t&̴qI\\x16=P<+[&F\\x06=\\\\V={\\x7f\\x19\\x01\\x0e<2+QF{\\x08Q\\x01<,\\x1b*d\\x01:\\x10D\\x11d=\\rFvT=;/==A9YڽZ1D<3US=MY\\\\=V;=\\x1absZ<\\x1fB=\\x0b[?_=?<:J=<-Ҝ<0<\\t5Zʝ=Z;5<ü[=\\x14лP⼊*\\x11=*N=!FՉ̼\\r;\\x12<\\u05fd\\nԽZ]\\'<%U@\\x174P_@]нF=A<&\\n\\x11v«#+=[閽\\x07f\\x19Kp0\\x08pq;mMꚽR漉\\x17=o\\x00=x?\\x07=I;\\x13.<\\x7fv=\\x150\\x1dP=0\\x05=!>J=\\x04*uچ=@>7ټE佛sV\\x10R\\x1e==P뼙{\\x0b<+^\\x17=[<\\x0eh\\x04\\x02=zӼHm\\n=\\x0e;:\\x1fє<1=|\\x08t5-peҜ:=\\x04˽hlz&=UUB(|5=&=\\x07\\x14/<+.<\\x05e;\\n<=$\\x1f=\\x042\\x03>w<ޖʼ衝=\\x05G=\\x7fR\\x17wql\\x12x%?;\\x04f\\x088b_=r\\x06<\\x1b<$n\\x0e=vs=\\x10\\x15`=\\x16J_Ѣ?\\x12T>=\\x15\\x06=W=37;Q\\t\\x00\\x18=\\x05q=Q;\\'W\\x05=\\x1a=$4=b6=|=!c=I=J<\\\\`ʍ:+<\\u07b5<\\x03<\\x15Xʼ\"e>\\x1cg=DB<\\x0e<\\x1bK\\x11;8ν<1\\n\\x1976{=/\\x05=;]I\\x1cK\\x1aT;_R[8H=:#=(2=\\x1a\\x03>1n=(d;!\\u07b2t<~\"b;*\\x1b/\\x0cT<]λ{\\x0b=Qԅ=ӦF\\x16q\\x18=A\\x17=씼{=\\x0c0\\x03Ѡ<\\'%<_u=z½1x^S\\x0c\\u05fdŗK=\\x17\\x10\\x16\\x1f!\\\\;yFe =-,d=\\x1dx<=QAһE\\x08j/==嶻<ݼN_[0;C<|ihfx懼\\t\\r\\x00w\\x16z\"9\\x11Dd,мTz5d\\x1bdb%<\\x15,\\u05cb[5,\\x0cM=/ μTB9\\x10lۊ=\\x17֨=cǼC=\\x06u=%?=\\\\J|9PF\\x0f\\x03>h\\x18=щ\\x1dq\\x0f=ߣ<\\x03\\x0e=nA<\\x16뻥⼽H8|v\\x15\\x12={<\\x00YEHq;\"1m<ܒžQ<י\\x07+\\x13,j\\x16\"=\\x05>\\rS<-\"g\\x1bc!=}hc`\\x18<}溡O=\\x12\\x04ɼ0/\\x10-\\'ar.Q;=LPE\\t&1-\\x12ν샄<\\'+=b\\x0b\\x08(ݼhe\\x14ԍ>=uz\\x7f69=%\\x02\\x12=Hhx\\x0f\\x01>\\x02:;/;=C<7kfk=\\x19=,=x=<\\x15]0= P=GsݠE=e=ú\\u05fcO#7\\x17=&g4\\r\\x04=(<\\x17-~BD\\x08R=7=Q\\x10\\x14T\\x066Iג<~;G_ý 뽜NWm\\x18F<<ͼ\\nd<Ĩh=Y-K2TG\\x08Vz=\\x0b(:rx=\\x18\\x1d;C\\x15\\t=6\\x14&aL.}\\x17=%S=\\x1b;gһ\\x19>AuA9\\x1f=A\"(\\x00>N;[Z=X\\x1b\\x15\\x12>-h\\x00C=\\x13Z=>aOEB=\\x14C=^R-<=!<-=\\x0c%<<\\x06\" M=\\x7f\\uea3cI<\\x11S\\x1e\\x1eE(qb=@\\x14=\\x05\\x027%mL<⛳=\\x06M|u*<<3iK\\x17A\\x1e\\x05Hug3$ͽ$;\\x04z==\\x0eƽhI^\\x16;z\\x0c\\x1b3ɼ\\x18\\'u><\\x02J=\\x0e*=OU \\x02\\x19=\\x19K<\\t=J=\\u05f8\\U000b573d=\\x18=d&=03<\\x1bF?\\x14ď(O<\\x12=\\x05Op\\x18ɞeHs;$a;B#:=\\x15*<\\x1b=\\x01V\\r=9\\x06=\\x13u<\\x1a;9/=\\x85=p\\x0b\"=i<:c=2\\x08\\x12;=OVW;Vb<Н<9,=\\x17ߺ\\x14:M9\\x08\\x0bV<_6=!Ub#=WX=u\\x11=?6=\\x06,<\\'\\x15t=;лwK-=H\\x11\\x036=\\x15<8xM\\x10=_\\x03D=\\x0b\\x08$G\\x0cr=m=<)$y\\x06=X=s%\\r\\x1dz\\x0e\\t<$\\tI=\\x01x\\x10;Y\\x0f<蓻bߺe c=>;\\x18u༎\\x10x~=ah<\\x070;#r=iD:?ئa2g\\x00=\\x1bą;g\\x12=OʃRF2=\\x11䛽%==^<̒\\x06=-@g<;ܼX\\x19=#b\\x0bb}xU;\\\\\\x08~=/&N(缸&\\x08ۆ=:p^<|僼½f\\x11=\\u05fdx<#;Ȼ=1I\\x0b\\x7f\\x0cR\\x11\\x14ʽuA<;\\rpr}\\x0f\\x18=Tp1gC<:\\x16{\\x19.<$5=AGl=-\\\\=hGEY>;2\\r==y{@\\x16Oƻ$o=\\x0b#j=~0> {\\x03kl/=ul\\x07ͼ\\x17>F1\\x1bYFؔ/\\x1d5M\\x07Jݏ=-\\x08xN>\\x7f;M\\x05u\\x19H@tC=<\\x0f\\x18Kz=\\x13=ጽ&=qZ\\x07=Mq=^ߣA*\\'\\x13\\x03=;A&s=u0ltn>\\t=bڼ@f\\'j\\x10\\x01=Ѽ\\x12C=6)vgi6\\x05\\x01l\\x15<\\x17m\\x15; =\\rL\\x13;ýC=\\x04лS\\x03_\\x02[=B/D>=5\\x19\\x03\\x13<\\r|K=\\'h<\\nB<>9T\\x1eh=ݨa=Ϳ-\\x00;=fK=t=}ظ;Ϧj<ݛ;\\x03}<-<\\x18;\\x1e.=\\x1en;\\x01G=L\\x10Q\\\\|\\x11Yo=u\\x0f\\x19%+=1P<:m;\\x07&==rQA\\x15ϼ\\x0b+<\\x02=h\\x0e9=I3K=5ͼ\\x04E7;ty|=\\x04Ӏ<\\x0c<\\x01\\x0e\\x18>\\x0f\\x14qiQ=yR:kX=\\x13|\\x0b=ǎI0s-Qߒ;{XB=\\r\\x046=y6EW=\\r<=X=\\x1a<\\x18U\\x15\\x02I\\x00Bg;~ =\\x7fv\\x16y\\'غ\\x19\\r\\x1b)(3\\x16Oj\\x0eA0=7L=dI\\r=A[=\\x02A;\\\\=o\\x00Ƽ)V¼Їh5\\x01=\\x06=h>ˠŐWxL=\\x04=v\\x7f)͓:\\x10;aZ\"\\x06/2\\x0b==\\t/&|f<ӽm\\x1fnx=+F\\n*<}w\\x07lI\\x00\\x02@=Bi\\x06=\\x1c\\x11v:/ٍ!\\x18(Ј`;<ᓟ\\x02R=\\x13>c{R=3Qٽ2ӄ\\x05<~<${Y=_i=Ib>=Y\\x1c<̠$>#=\\x01j|\\x19Q=6l=\\x15q-Sf<\\x1d\\x07$=\\x1f\\x0e=>\\x03$L~<\\x01\\x02a\\x1dI<\\x14=ZnS3m!~͈\\x05\\u07bb\\x1e=cHf\\x11h@<1ki$3=\\x14\\x08.\\x17w>=\\x03)=><\\x1d\\x10b괺Be=\\x1b\\x003=Y<\\x156e<1bL=D\\x03\\x0b]b\\x14<3 >\\x02\\n:2*=\"8,QʽQ=j\\x1d\\x16w!>\\x13<\\x1ey!\\x00U<\\x13u<\\x12<\\x14C[:c=5<@\\x0bM=\\x05\\x182;f<ӭ==\\x03b;\\x0bН<\\x1b=\\r\\tșL[{\\x16;!μU;\\nZ<\\x0f\\x17=ߑ=\\uec09dT=^Լ<\\x0c;\\x196(=\\x08\\x1b<\\x01=!\\x17<\\x0f.=yq=~\\x1a\\x1f:G0(H]X=d\\x10=Ge@[\\x06F<', 'title': 'John Wick', 'rating': '8'}, Document {'id': '6', 'payload': None, 'genre': 'action', 'description': 'Batman faces off against the Joker, a criminal mastermind who threatens to plunge Gotham into chaos.', 'vector': ':A%=Em5\\x0eGh=\\x035%\\x01P\\x1eq\\x1d\\x1c=N==\\r\\x04\\\\8E= ,==4\\x01G==(<\\x02/)=PK6\\x04Y螉\\x0eྲྀ8:2jt|=,\\x0c6\\x17am<&=\\t\\x18>_\\x108<\\x0f!lQ^\\x0e>1K=<*F\\x01Q.hЌg\\r\\x01<Ԭ<@<0\\r\\x11=\\rq\\rT\\'P=y\\x17ml>DM}=rH5=\\x0f\\x13Ϋ=D\\x03;\\rR=a=4=\\x13q\\x07=ޭ\\x01=\\x17<.J\\x01=Gy\\t\\x13S=\\'6k\\x00\\x07;Oؽf\\x08<2ݼ<(}E=M{JֽY=Vj\\x18A=CT@]=Jj<18\\x1a=ぎ=\\r8P{<.4Ž\\x0f=\\\\g==+D=Vce=6xUǽ-\\r+=O=,ü0C\\x05R=\\nrSZ=[L\\x01\\nnV=Ѝ\\x19W=:w=4v=C\\x1b@<:y;\\nh=ڙ=C\\uef1e=@ے=9_S8;e<\\x1d\\x1b=rDK-S새;\\t\\x16=\\x1a\\x18~=r6\\x19=r=1?;\\x16\\r\\x18\\x1e;<\\x15j4ߜP<\\nAR\\x06=ߕ$\\x11=hgv\\x18>\\x14ѽO=Ѷ<@6=\\x03o=\\t\\x01|>A=\\x00!.c3\\\\7L\\x01==-I ];ջͣ<[\\x15\\x0cҩ=Q\\x19Rk$\\x17Oc\\x11B}j\\x02\\roy=~=4==\\r-=(=Zҹ<`@j\\x1c(\\x1b=\\x10=(x:h#pI=x\\u05fb\\\\<\\x1d\\x1cY|\\x0c=Aˡ?\\x18\\x0f\\x04n=?5d\\'=d3;\\x06`ܻ\\x101=^)\\x0c\\x13B<\">=s\\x06=\\x08=̽|\\x1f!{=i\\x19Dm\\x192;<-ſ?[R@=|\\x0f%<\\x01ؕ4\\x13$=Ӽ\\x1c-F!ﵼ\\x01Hf{\\ue17d=\\x12TB<\\x064Ἥ\\x13:\\x11\\x1b_:2;W\\x0c=Xx;m=\\x02= <+*x=-\"P=:\\\\=k\\x0c=\\x12L42\\x15\\x17!q>s=|;\\x14\\x1eKj;>v\\x1e=!=d&=s<<\\x16<4\"\\x16\"u\\x0e>\\x0b\\x05Ɍ.kY-pض\\x12\\x19<[*\\x13=\\x1ej\\t\\x7f=]p<.\\x1f=0f~;%\\n_=?;\\x1eC\\x19W\\x04=FF<_s<;=B=վȤ\\x14r\\x00\\x0c0<\\na.t=s\\x19P$\\'%\\x19\\x05===\\x7fWE}A\\r\\r*<`\\x05=TF= ^=\\x0c0=FA;\\x17G\\x01%\\x05U%=\\x0ck5\\x08Hżb{$weight: 1}) | (@description:(%superhero%)=>{$weight: 10}))') \\\n", + " .return_fields(\"title\", \"genre\", \"rating\", \"description\") \\\n", + " .paging(0, 3) \\\n", + " .dialect(2)\n", + "\n", + "res = client.ft(index_name).search(query)\n", + "res.docs" + ] + }, { "cell_type": "code", "execution_count": 20, @@ -663,7 +777,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "Python 3", "language": "python", "name": "python3" }, diff --git a/python-recipes/vector-search/04_advanced_queries.ipynb b/python-recipes/vector-search/04_advanced_queries.ipynb deleted file mode 100644 index 85025094..00000000 --- a/python-recipes/vector-search/04_advanced_queries.ipynb +++ /dev/null @@ -1,809 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "cbba56a9", - "metadata": {}, - "source": [ - "![Redis](https://redis.io/wp-content/uploads/2024/04/Logotype.svg?auto=webp&quality=85,75&width=120)\n", - "# Advanced queries with Redis\n", - "## Let's Begin!\n", - "\"Open\n" - ] - }, - { - "cell_type": "markdown", - "id": "0b80de6b", - "metadata": {}, - "source": [ - "## Prepare data\n", - "\n", - "In this examples we will load a list of movie objects with the following attributes: `title`, `rating`, `description`, and `genre`. \n", - "\n", - "For the vector part of our vector search we will embed the description so that user's can search for movies that best match what they're looking for.\n", - "\n", - "**If you are running this notebook locally**, FYI you may not need to perform this step at all." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "b966a9b5", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Cloning into 'temp_repo'...\n", - "remote: Enumerating objects: 204, done.\u001b[K\n", - "remote: Counting objects: 100% (52/52), done.\u001b[K\n", - "remote: Compressing objects: 100% (28/28), done.\u001b[K\n", - "remote: Total 204 (delta 37), reused 24 (delta 24), pack-reused 152\u001b[K\n", - "Receiving objects: 100% (204/204), 9.47 MiB | 10.76 MiB/s, done.\n", - "Resolving deltas: 100% (64/64), done.\n", - "mv: temp_repo/python-recipes/vector-search/resources: No such file or directory\n" - ] - } - ], - "source": [ - "# NBVAL_SKIP\n", - "!git clone https://github.com/redis-developer/redis-ai-resources.git temp_repo\n", - "!mv temp_repo/python-recipes/vector-search/resources .\n", - "!rm -rf temp_repo" - ] - }, - { - "cell_type": "markdown", - "id": "19bdc2a5-2192-4f5f-bd6e-7c956fd0e230", - "metadata": {}, - "source": [ - "## Packages" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c620286e", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Note: you may need to restart the kernel to use updated packages.\n" - ] - } - ], - "source": [ - "%pip install -q redis numpy sentence-transformers" - ] - }, - { - "cell_type": "markdown", - "id": "323aec7f", - "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": "code", - "execution_count": null, - "id": "2cb85a99", - "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", - "id": "7c5dbaaf", - "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`" - ] - }, - { - "cell_type": "markdown", - "id": "1d4499ae", - "metadata": {}, - "source": [ - "### 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": 8, - "id": "aefda1d1", - "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": "markdown", - "id": "f8c6ef53", - "metadata": {}, - "source": [ - "### Create redis client" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "370c1fcc", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from redis import Redis\n", - "client = Redis.from_url(REDIS_URL)\n", - "client.ping()" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "458fc773", - "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": 4, - "id": "8d561462", - "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", - "/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": [ - "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": 5, - "id": "9946a382", - "metadata": {}, - "outputs": [], - "source": [ - "# Note: convert embedding array to bytes for storage in Redis Hash data type\n", - "movie_data = [\n", - " {\n", - " **movie,\n", - " \"vector\": embed_text(model, movie[\"description\"])\n", - " } for movie in movies\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "8797fcc6", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'id': 1,\n", - " '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'\\x8bf|=\\xc3`\\n;\\xf2\\x91\\xb7;?\\xcb~\\xbd\\xdfd\\xce\\xbb\\xc7\\x16J=H\\xa7?=\\xdfv\\x95\\x17\\xbeA\\x1e\\x05\\xb9Hu\\xbfg3\\xbd$\\xcd\\xbd\\xbd\\xa1$\\xf7;\\x04\\xf5z=\\xfc\\xb4\\x8c=\\x89\\x0e\\xc6\\xbdhI\\x90\\xbd^\\x16\\xbd;z\\xe7\\x0c\\xbd\\x1b3\\xc9\\xbc\\x89\\xf8\\xbb\\xbc\\x18\\'u\\xbb>\\x8f\\xca<\\x02\\x80J=\\x0e\\xaf*=\\x8dOU\\xbd\\xcf\\xf0\\x95\\xbc \\x02\\x19=\\x19\\xf4K<\\xc5\\xc2\\t=J\\x83\\xac=\\x95\\xd7\\xb8\\xbd\\xf2\\xb5\\x9c\\xbd=\\x85\\x18=\\x94d&=03\\xf8<\\xee\\xf7\\x88<\\x80v\\xf2\\xbb9=[\\xbdG\\xac\\xee\\xbb<:A\\xbd\\xe1d\\x19\\xbd!d\\xf2\\xbb\\x1d\\xbax;\\xec;O<\\xd21,\\xbc\\xec\\xae\\xae=r\\x00-\\xbc\"\\x06\\xae\\xbdl\\xd6\\x1a=\\xc4\\xbf\\xcd=\\x19\\x150=\\xe3\\xf1\\x9d\\xbc\\xa6GK=\\xb2\\xb8 =\\xb2\\xf1I\\xbd-e\\x9e\\xbb\\xe9\\x8a\\xf7:\\x88\\xf8\\x1c=\\x7f\\xba\\xde<\\xd2n\\x16\\xbb\\xb4\\\\p\\xbb\\xd4\\xd5<<\\x89\\xa5\\xa3\\xb8\\xc79s<=4&<\\x84\\x1c\\x18<\\x18\\xd9-\\xbd\\xdf\\xe6\\x98<\\x15\\xa1N=\\xa2/\\xa5=\\x1d\\xf3\\xdd<\\x17L\\x13<\\x10\\x10\\xce\\xbac\\x9e\\xdc\\xbc\\xa68\\x05=+\\xa1\\xf5\\xbd\\x84\\x1bF\\xbd\\xa0?\\x14\\xbe\\xc4\\x8f(\\xbd\\xe6O\\x89\\xbd\\xf7\\xad\\xd4<\\xa7\\x12\\xc3=\\xaf\\x05O\\xbd\\x99\\x8ep\\xbc\\x18\\xb5\\xac\\xbc\\xc9\\x9ee\\xbdH\\x8es;$a\\xc1;\\xd9\\xfaB\\xbd\\xa8#\\xfe:\\x92\\xe6\\xf4=\\xcd\\x15*<\\x86\\xf8\\x1b=\\x01\\xfcV\\xbd\\xd3\\xd1\\r=9\\xee\\x06=\\x13u\\xba\\xbd\\xf7\\xa3\\xd6<\\x1a\\xec\\xd9;\\xb79/=\\xa4\\xc2\\x85=p\\x0b\"=\\xe1i\\xef<:\\xe8c=\\xfb2\\x08\\xbe\\xce\\x12;=OVW;V\\xa4b<\\xd0\\x9d\\xb7<\\x87r;\\xbdqz\\x91\\xbcV\\x00<\\xbd\\xfe\\x19\\xa3<\\xeaJ%\\xbc!\\xe7\\xbf\\xbb\\x7f\\x87\\x12=\\x94\\x1d\\x95=b|\\xfd\\xbc\\xf3\\xf1\\xd1\\xbd\\xf5y\\x84;\\xc9\\tu=]\\x8ai<3\\x91R\\xbd\\xec\\xf3m\\xbd\\x93\\xb83=V\\xedF=\\x1f\\xf3\\xd1\\x08yA\\xba<#\\xacO\\xbd\\x01\\x0f\\xc7;\\x7f\\xf4\\x04\\xbdP\\x82\\x92\\xbd\\x9b\\xddD=p\\xd8;\\xbc\\xd3;\\xf4\\xbc\\xb3\\x8f\\x97\\xbd1\\\\\\r\\xbd\\xea\\x8c\\xf5\\xbd\\x8c\\x13(=\\x9e\\xc8\\xc6=\\xa3\\xed\\x1a=\\x98\\xa8\\xf8=\\x84\\xc1\\xee\\xbc\\xcd-\\x18\\xbb\\xf5~;<\\xd6F\\t\\xbd\\x14\\x08\\x17=\\xa5\\xa5\\x1e=\\x14K\\xcb\\xbd.\\xf7\\x8c\\xbdyb\\xed\\xbb\\x86[\\x19\\xbc]\\x0c\\x13\\xbcgq\\x83=\\xf0wd\\xbd\\xe3\\xc7\\xd1\\xbb8lY\\xbc\\xa7|a=3\\xcf\\xfd\\xbc\\x1f\\xa5\\x83\\xbb\\x99O\\x19\\xbd6\\x02]\\xbd\\xbb\\xeaz=\\x036\\x9c=:^\\xa9\\xbd)^9\\xbcg\\xe4N\\xbcs\\x07x\\xbd\\x18{\\xa0=:\\x9f\\x96<\\xecq8\\xba\\x9e\\xbb=\\xbd\\xe4|(<\\x96\\xdf\\xb4\\xbbl\\xc9\\x0b\\xbd\\xc4\\x01\\x95\\xbd\\xf7\\xc6T=\\tp\\xd1{{$weight: 1}}) | (@description:({tokenize(user_query2)})=>{{$weight: 10}}))') \\\n", - " .return_fields(\"title\", \"genre\", \"rating\", \"description\") \\\n", - " .dialect(2)\n", - "\n", - "res = client.ft(index_name).search(query)\n", - "res.docs" - ] - }, - { - "cell_type": "markdown", - "id": "4f308e8d", - "metadata": {}, - "source": [ - "## Scenario 4: Ability to have logical operations\n", - "\n", - "q=field1:(\"sample data value 1\")^ || field2:(\"sample data value 2\")\n", - "\n", - "q=field1:(\"sample data value 1\")^ && field2:(\"sample data value 2\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8a493ae0", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Document {'id': '9', 'payload': None, 'title': 'The Avengers', 'genre': 'action', 'rating': '8', 'description': \"Earth's mightiest heroes come together to stop an alien invasion that threatens the entire planet.\"},\n", - " Document {'id': '0', 'payload': None, 'title': 'Explosive Pursuit', 'genre': 'action', 'rating': '7', 'description': 'A daring cop chases a notorious criminal across the city in a high-stakes game of cat and mouse.'}]" - ] - }, - "execution_count": 48, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Search with full text search for movies that directly mention \"criminal mastermind\" in the description\n", - "\n", - "user_query1 = \"High tech\"\n", - "user_query2 = \"heroes villains\"\n", - "\n", - "def tokenize(query):\n", - " return \" | \".join(query.split(\" \")).lower()\n", - "\n", - "query = Query(f'((@rating:[7, inf+]) & (@description:({tokenize(user_query1)})=>{{$weight: 1}}) | (@description:({tokenize(user_query2)})=>{{$weight: 10}}))') \\\n", - " .return_fields(\"title\", \"genre\", \"rating\", \"description\") \\\n", - " .dialect(2)\n", - "\n", - "res = client.ft(index_name).search(query)\n", - "res.docs" - ] - }, - { - "cell_type": "markdown", - "id": "1f73c402", - "metadata": {}, - "source": [ - "## Scenario 5: Ability to specific type of algorithm.   \n", - "\n", - "q=field1:(\"sample data value 1\")^ && field2:(\"sample data value 2\")&defType=edismax " - ] - }, - { - "cell_type": "code", - "execution_count": 59, - "id": "c0d7ab60", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Document {'id': '9', 'payload': None, 'score': 4.0, 'title': 'The Avengers', 'genre': 'action', 'rating': '8', 'description': \"Earth's mightiest heroes come together to stop an alien invasion that threatens the entire planet.\"},\n", - " Document {'id': '10', 'payload': None, 'score': 1.3333333333333333, 'title': 'Toy Story', 'genre': 'comedy', 'rating': '8', 'description': \"Woody, a good-hearted cowboy doll who belongs to a young boy named Andy, sees his position as Andy's favorite toy jeopardized when his parents buy him a Buzz Lightyear action figure. Even worse, the arrogant Buzz thinks he's a real spaceman on a mission to return to his home planet.\"}]" - ] - }, - "execution_count": 59, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "index_name = \"movies\" # variable\n", - "\n", - "user_query = \"cowboys and aliens\"\n", - "\n", - "user_query = Query(tokenize(user_query)) \\\n", - " .scorer(\"TFIDF\") \\\n", - " .with_scores() \\\n", - " .return_fields(\"title\", \"genre\", \"rating\", \"description\") \\\n", - " .paging(0, 10) # limits the amount of results to 10\n", - "\n", - "res = client.ft(index_name).search(user_query)\n", - "res.docs" - ] - }, - { - "cell_type": "markdown", - "id": "610f006f", - "metadata": {}, - "source": [ - "## Scenario 6: Ability to query certain type of document which value greater than certain number\n", - "\n", - "q=field1:(\"sample data value 1\")^ && field2:(\"sample data value 2\")&fq=field3:[50+TO+*] \n", - "\n", - "=> shown with ratings with scenario 4" - ] - }, - { - "cell_type": "markdown", - "id": "1ce1601d", - "metadata": {}, - "source": [ - "## Scenario 7: Ability to return score for each document.\n", - "\n", - "=> scores return shown in other examples" - ] - }, - { - "cell_type": "markdown", - "id": "4d83434b", - "metadata": {}, - "source": [ - "## Scenario 8: vector search\n", - "\n", - "Beyond the capabilities shown here for feature parody, redis offers vector search which can combined with all the methods above to facilitate more powerful queries. Implementing vector search is very easy (especially with the [redis vector library](https://github.com/redis/redis-vl-python)). \n", - "\n", - "In the following example you can see how event thought the word **sentimental** doesn't show up anywhere in the corpus we're still able to effectively find movies that match the semantic meaning of that word." - ] - }, - { - "cell_type": "code", - "execution_count": 64, - "id": "09c55f39", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Document {'id': '17', 'payload': None, 'title': 'Despicable Me', 'genre': 'comedy', 'rating': '7', 'description': 'When a criminal mastermind uses a trio of orphan girls as pawns for a grand scheme, he finds their love is profoundly changing him for the better.'},\n", - " Document {'id': '3', 'payload': None, 'title': 'Black Widow', 'genre': 'action', 'rating': '7', 'description': 'Natasha Romanoff confronts her dark past and family ties as she battles a new enemy.'},\n", - " Document {'id': '15', 'payload': None, 'title': 'The Incredibles', 'genre': 'comedy', 'rating': '8', 'description': \"A family of undercover superheroes, while trying to live the quiet suburban life, are forced into action to save the world. Bob Parr (Mr. Incredible) and his wife Helen (Elastigirl) were among the world's greatest crime fighters, but now they must assume civilian identities and retreat to the suburbs to live a 'normal' life with their three children. However, the family's desire to help the world pulls them back into action when they face a new and dangerous enemy.\"}]" - ] - }, - "execution_count": 64, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from redis.commands.search.query import Query\n", - "\n", - "user_query = \"Sentimental movies\"\n", - "\n", - "embedded_user_query = embed_text(model, user_query)\n", - "\n", - "# Note: dialect 2 and above required for vector search\n", - "query = Query(\"(*)=>[KNN 3 @vector $vec_param AS dist]\").sort_by(\"dist\").dialect(2).return_fields(\"title\", \"genre\", \"rating\", \"description\").paging(0, 3)\n", - "\n", - "res = client.ft(index_name).search(query, query_params = {'vec_param': embedded_user_query})\n", - "res.docs" - ] - }, - { - "cell_type": "markdown", - "id": "6bd27cb3", - "metadata": {}, - "source": [ - "## Range queries\n", - "\n", - "Range queries allow you to set a pre defined \"threshold\" for which we want to return documents. This is helpful when you only want documents with a certain distance from the search query." - ] - }, - { - "cell_type": "code", - "execution_count": 65, - "id": "cafe1795", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Top 6 movies: [('The Incredibles', 'comedy', '8'), ('Black Widow', 'action', '7'), ('Despicable Me', 'comedy', '7'), ('Shrek', 'comedy', '8'), ('Monsters, Inc.', 'comedy', '8'), ('Aladdin', 'comedy', '8')]\n" - ] - } - ], - "source": [ - "user_query = \"Family friendly fantasy movies\"\n", - "\n", - "embedded_user_query = embed_text(model, user_query)\n", - "\n", - "query = (\n", - " Query(\"@vector:[VECTOR_RANGE $radius $vector]=>{$YIELD_DISTANCE_AS: vector_distance}\")\n", - " .sort_by(\"vector_distance\")\n", - " .return_fields(\"title\", \"rating\", \"genre\", \"vector_distance\")\n", - " .dialect(2)\n", - ")\n", - "\n", - "# Find all vectors within 0.8 of the query vector\n", - "query_params = {\n", - " \"radius\": 0.8,\n", - " \"vector\": embedded_user_query\n", - "}\n", - "\n", - "res = client.ft(index_name).search(query, query_params)\n", - "print_results(res)\n" - ] - }, - { - "cell_type": "markdown", - "id": "a1586ea7", - "metadata": {}, - "source": [ - "Like the queries above, we can also chain additional filters and conditional operators with range queries. The following adds an `or` condition that returns vector search within the defined range or with a rating at or above 9." - ] - }, - { - "cell_type": "code", - "execution_count": 66, - "id": "d3110324", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Top 3 movies: [('The Incredibles', 'comedy', '8'), ('The Dark Knight', 'action', '9'), ('Inception', 'action', '9')]\n" - ] - } - ], - "source": [ - "user_query = \"Family friendly fantasy movies\"\n", - "\n", - "embedded_user_query = embed_text(model, user_query)\n", - "\n", - "query = (\n", - " Query(\"@rating:[9 +inf] | @vector:[VECTOR_RANGE $radius $vector]=>{$YIELD_DISTANCE_AS: vector_distance}\")\n", - " .sort_by(\"vector_distance\")\n", - " .return_fields(\"title\", \"rating\", \"genre\", \"vector_distance\")\n", - " .dialect(2)\n", - ")\n", - "\n", - "# Find all vectors within 0.8 of the query vector\n", - "query_params = {\n", - " \"radius\": 0.7,\n", - " \"vector\": embedded_user_query\n", - "}\n", - "\n", - "res = client.ft(index_name).search(query, query_params)\n", - "print_results(res)" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "1902b43b", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# clean up!\n", - "client.flushall()" - ] - } - ], - "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": 5 -} From 2afc1fbb85c23398bbcf96590f00ae7efb182fdf Mon Sep 17 00:00:00 2001 From: Robert Shelton Date: Thu, 1 May 2025 11:27:01 -0400 Subject: [PATCH 05/10] pin version --- python-recipes/vector-search/00_redispy.ipynb | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/python-recipes/vector-search/00_redispy.ipynb b/python-recipes/vector-search/00_redispy.ipynb index 0766bd5f..466bac38 100644 --- a/python-recipes/vector-search/00_redispy.ipynb +++ b/python-recipes/vector-search/00_redispy.ipynb @@ -63,20 +63,33 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 24, "id": "c620286e", "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": [ + "\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;49m25.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": [ - "%pip install -q redis numpy sentence-transformers" + "%pip install -q \"redis>=5.0.5\" numpy sentence-transformers" ] }, { @@ -627,7 +640,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": null, "id": "d3110324", "metadata": {}, "outputs": [ @@ -677,7 +690,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": null, "id": "3307ab80", "metadata": {}, "outputs": [ From 6047a4b083e4d1d9b1d03752724c0d57fa30342e Mon Sep 17 00:00:00 2001 From: Robert Shelton Date: Thu, 1 May 2025 14:31:56 -0400 Subject: [PATCH 06/10] fix for updated redis --- .python-version | 2 +- python-recipes/vector-search/00_redispy.ipynb | 83 ++++------- .../vector-search/02_hybrid_search.ipynb | 140 +++++++++--------- 3 files changed, 103 insertions(+), 122 deletions(-) diff --git a/.python-version b/.python-version index b6d8b761..2419ad5b 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -3.11.8 +3.11.9 diff --git a/python-recipes/vector-search/00_redispy.ipynb b/python-recipes/vector-search/00_redispy.ipynb index 466bac38..9d49ee85 100644 --- a/python-recipes/vector-search/00_redispy.ipynb +++ b/python-recipes/vector-search/00_redispy.ipynb @@ -148,7 +148,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 57, "id": "aefda1d1", "metadata": {}, "outputs": [], @@ -174,7 +174,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 58, "id": "370c1fcc", "metadata": {}, "outputs": [ @@ -184,7 +184,7 @@ "True" ] }, - "execution_count": 2, + "execution_count": 58, "metadata": {}, "output_type": "execute_result" } @@ -197,7 +197,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 59, "id": "458fc773", "metadata": {}, "outputs": [], @@ -210,21 +210,10 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 60, "id": "8d561462", "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", - "/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": [ "import numpy as np\n", "from sentence_transformers import SentenceTransformer\n", @@ -238,7 +227,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 61, "id": "9946a382", "metadata": {}, "outputs": [], @@ -254,7 +243,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 62, "id": "8797fcc6", "metadata": {}, "outputs": [ @@ -269,7 +258,7 @@ " 'vector': b'\\x8bf|=\\xc3`\\n;\\xf2\\x91\\xb7;?\\xcb~\\xbd\\xdfd\\xce\\xbb\\xc7\\x16J=H\\xa7?=\\xdfv\\x95\\x17\\xbeA\\x1e\\x05\\xb9Hu\\xbfg3\\xbd$\\xcd\\xbd\\xbd\\xa1$\\xf7;\\x04\\xf5z=\\xfc\\xb4\\x8c=\\x89\\x0e\\xc6\\xbdhI\\x90\\xbd^\\x16\\xbd;z\\xe7\\x0c\\xbd\\x1b3\\xc9\\xbc\\x89\\xf8\\xbb\\xbc\\x18\\'u\\xbb>\\x8f\\xca<\\x02\\x80J=\\x0e\\xaf*=\\x8dOU\\xbd\\xcf\\xf0\\x95\\xbc \\x02\\x19=\\x19\\xf4K<\\xc5\\xc2\\t=J\\x83\\xac=\\x95\\xd7\\xb8\\xbd\\xf2\\xb5\\x9c\\xbd=\\x85\\x18=\\x94d&=03\\xf8<\\xee\\xf7\\x88<\\x80v\\xf2\\xbb9=[\\xbdG\\xac\\xee\\xbb<:A\\xbd\\xe1d\\x19\\xbd!d\\xf2\\xbb\\x1d\\xbax;\\xec;O<\\xd21,\\xbc\\xec\\xae\\xae=r\\x00-\\xbc\"\\x06\\xae\\xbdl\\xd6\\x1a=\\xc4\\xbf\\xcd=\\x19\\x150=\\xe3\\xf1\\x9d\\xbc\\xa6GK=\\xb2\\xb8 =\\xb2\\xf1I\\xbd-e\\x9e\\xbb\\xe9\\x8a\\xf7:\\x88\\xf8\\x1c=\\x7f\\xba\\xde<\\xd2n\\x16\\xbb\\xb4\\\\p\\xbb\\xd4\\xd5<<\\x89\\xa5\\xa3\\xb8\\xc79s<=4&<\\x84\\x1c\\x18<\\x18\\xd9-\\xbd\\xdf\\xe6\\x98<\\x15\\xa1N=\\xa2/\\xa5=\\x1d\\xf3\\xdd<\\x17L\\x13<\\x10\\x10\\xce\\xbac\\x9e\\xdc\\xbc\\xa68\\x05=+\\xa1\\xf5\\xbd\\x84\\x1bF\\xbd\\xa0?\\x14\\xbe\\xc4\\x8f(\\xbd\\xe6O\\x89\\xbd\\xf7\\xad\\xd4<\\xa7\\x12\\xc3=\\xaf\\x05O\\xbd\\x99\\x8ep\\xbc\\x18\\xb5\\xac\\xbc\\xc9\\x9ee\\xbdH\\x8es;$a\\xc1;\\xd9\\xfaB\\xbd\\xa8#\\xfe:\\x92\\xe6\\xf4=\\xcd\\x15*<\\x86\\xf8\\x1b=\\x01\\xfcV\\xbd\\xd3\\xd1\\r=9\\xee\\x06=\\x13u\\xba\\xbd\\xf7\\xa3\\xd6<\\x1a\\xec\\xd9;\\xb79/=\\xa4\\xc2\\x85=p\\x0b\"=\\xe1i\\xef<:\\xe8c=\\xfb2\\x08\\xbe\\xce\\x12;=OVW;V\\xa4b<\\xd0\\x9d\\xb7<\\x87r;\\xbdqz\\x91\\xbcV\\x00<\\xbd\\xfe\\x19\\xa3<\\xeaJ%\\xbc!\\xe7\\xbf\\xbb\\x7f\\x87\\x12=\\x94\\x1d\\x95=b|\\xfd\\xbc\\xf3\\xf1\\xd1\\xbd\\xf5y\\x84;\\xc9\\tu=]\\x8ai<3\\x91R\\xbd\\xec\\xf3m\\xbd\\x93\\xb83=V\\xedF=\\x1f\\xf3\\xd1\\x08yA\\xba<#\\xacO\\xbd\\x01\\x0f\\xc7;\\x7f\\xf4\\x04\\xbdP\\x82\\x92\\xbd\\x9b\\xddD=p\\xd8;\\xbc\\xd3;\\xf4\\xbc\\xb3\\x8f\\x97\\xbd1\\\\\\r\\xbd\\xea\\x8c\\xf5\\xbd\\x8c\\x13(=\\x9e\\xc8\\xc6=\\xa3\\xed\\x1a=\\x98\\xa8\\xf8=\\x84\\xc1\\xee\\xbc\\xcd-\\x18\\xbb\\xf5~;<\\xd6F\\t\\xbd\\x14\\x08\\x17=\\xa5\\xa5\\x1e=\\x14K\\xcb\\xbd.\\xf7\\x8c\\xbdyb\\xed\\xbb\\x86[\\x19\\xbc]\\x0c\\x13\\xbcgq\\x83=\\xf0wd\\xbd\\xe3\\xc7\\xd1\\xbb8lY\\xbc\\xa7|a=3\\xcf\\xfd\\xbc\\x1f\\xa5\\x83\\xbb\\x99O\\x19\\xbd6\\x02]\\xbd\\xbb\\xeaz=\\x036\\x9c=:^\\xa9\\xbd)^9\\xbcg\\xe4N\\xbcs\\x07x\\xbd\\x18{\\xa0=:\\x9f\\x96<\\xecq8\\xba\\x9e\\xbb=\\xbd\\xe4|(<\\x96\\xdf\\xb4\\xbbl\\xc9\\x0b\\xbd\\xc4\\x01\\x95\\xbd\\xf7\\xc6T=\\tp\\xd1\\x17A\\x1e\\x05Hug3$ͽ$;\\x04z==\\x0eƽhI^\\x16;z\\x0c\\x1b3ɼ\\x18\\'u><\\x02J=\\x0e*=OU \\x02\\x19=\\x19K<\\t=J=\\u05f8\\U000b573d=\\x18=d&=03<\\x1bF?\\x14ď(O<\\x12=\\x05Op\\x18ɞeHs;$a;B#:=\\x15*<\\x1b=\\x01V\\r=9\\x06=\\x13u<\\x1a;9/=\\x85=p\\x0b\"=i<:c=2\\x08\\x12;=OVW;Vb<Н<9,=\\x17ߺ\\x14:M9\\x08\\x0bV<_6=!Ub#=WX=u\\x11=?6=\\x06,<\\'\\x15t=;лwK-=H\\x11\\x036=\\x15<8xM\\x10=_\\x03D=\\x0b\\x08$G\\x0cr=m=<)$y\\x06=X=s%\\r\\x1dz\\x0e\\t<$\\tI=\\x01x\\x10;Y\\x0f<蓻bߺe c=>;\\x18u༎\\x10x~=ah<\\x070;#r=iD:?ئa2g\\x00=\\x1bą;g\\x12=OʃRF2=\\x11䛽%==^<̒\\x06=-@g<;ܼX\\x19=#b\\x0bb}xU;\\\\\\x08~=/&N(缸&\\x08ۆ=:p^<|僼½f\\x11=\\u05fdx<#;Ȼ=1I\\x0b\\x7f\\x0cR\\x11\\x14ʽuA<;\\rpr}\\x0f\\x18=Tp1gC<:\\x16{\\x19.<$5=AGl=-\\\\=hGEY>;2\\r==y{@\\x16Oƻ$o=\\x0b#j=~0> {\\x03kl/=ul\\x07ͼ\\x17>F1\\x1bYFؔ/\\x1d5M\\x07Jݏ=-\\x08xN>\\x7f;M\\x05u\\x19H@tC=<\\x0f\\x18Kz=\\x13=ጽ&=qZ\\x07=Mq=^ߣA*\\'\\x13\\x03=;A&s=u0ltn>\\t=bڼ@f\\'j\\x10\\x01=Ѽ\\x12C=6)vgi6\\x05\\x01l\\x15<\\x17m\\x15; =\\rL\\x13;ýC=\\x04лS\\x03_\\x02[=B/D>=5\\x19\\x03\\x13<\\r|K=\\'h<\\nB<>9T\\x1eh=ݨa=Ϳ-\\x00;=fK=t=}ظ;Ϧj<ݛ;\\x03}<-<\\x18;\\x1e.=\\x1en;\\x01G=L\\x10Q\\\\|\\x11Yo=u\\x0f\\x19%+=1P<:m;\\x07&==rQA\\x15ϼ\\x0b+<\\x02=h\\x0e9=I3K=5ͼ\\x04E7;ty|=\\x04Ӏ<\\x0c<\\x01\\x0e\\x18>\\x0f\\x14qiQ=yR:kX=\\x13|\\x0b=ǎI0s-Qߒ;{XB=\\r\\x046=y6EW=\\r<=X=\\x1a<\\x18U\\x15\\x02I\\x00Bg;~ =\\x7fv\\x16y\\'غ\\x19\\r\\x1b)(3\\x16Oj\\x0eA0=7L=dI\\r=A[=\\x02A;\\\\=o\\x00Ƽ)V¼Їh5\\x01=\\x06=h>ˠŐWxL=\\x04=v\\x7f)͓:\\x10;aZ\"\\x06/2\\x0b==\\t/&|f<ӽm\\x1fnx=+F\\n*<}w\\x07lI\\x00\\x02@=Bi\\x06=\\x1c\\x11v:/ٍ!\\x18(Ј`;<ᓟ\\x02R=\\x13>c{R=3Qٽ2ӄ\\x05<~<${Y=_i=Ib>=Y\\x1c<̠$>#=\\x01j|\\x19Q=6l=\\x15q-Sf<\\x1d\\x07$=\\x1f\\x0e=>\\x03$L~<\\x01\\x02a\\x1dI<\\x14=ZnS3m!~͈\\x05\\u07bb\\x1e=cHf\\x11h@<1ki$3=\\x14\\x08.\\x17w>=\\x03)=><\\x1d\\x10b괺Be=\\x1b\\x003=Y<\\x156e<1bL=D\\x03\\x0b]b\\x14<3 >\\x02\\n:2*=\"8,QʽQ=j\\x1d\\x16w!>\\x13<\\x1ey!\\x00U<\\x13u<\\x12<\\x14C[:c=5<@\\x0bM=\\x05\\x182;f<ӭ==\\x03b;\\x0bН<\\x1b=\\r\\tșL[{\\x16;!μU;\\nZ<\\x0f\\x17=ߑ=\\uec09dT=^Լ<\\x0c;\\x196(=\\x08\\x1b<\\x01=!\\x17<\\x0f.=yq=~\\x1a\\x1f:G0(H]X=d\\x10=Ge@[\\x06F<', 'title': 'John Wick', 'rating': '8'}, Document {'id': '6', 'payload': None, 'genre': 'action', 'description': 'Batman faces off against the Joker, a criminal mastermind who threatens to plunge Gotham into chaos.', 'vector': ':A%=Em5\\x0eGh=\\x035%\\x01P\\x1eq\\x1d\\x1c=N==\\r\\x04\\\\8E= ,==4\\x01G==(<\\x02/)=PK6\\x04Y螉\\x0eྲྀ8:2jt|=,\\x0c6\\x17am<&=\\t\\x18>_\\x108<\\x0f!lQ^\\x0e>1K=<*F\\x01Q.hЌg\\r\\x01<Ԭ<@<0\\r\\x11=\\rq\\rT\\'P=y\\x17ml>DM}=rH5=\\x0f\\x13Ϋ=D\\x03;\\rR=a=4=\\x13q\\x07=ޭ\\x01=\\x17<.J\\x01=Gy\\t\\x13S=\\'6k\\x00\\x07;Oؽf\\x08<2ݼ<(}E=M{JֽY=Vj\\x18A=CT@]=Jj<18\\x1a=ぎ=\\r8P{<.4Ž\\x0f=\\\\g==+D=Vce=6xUǽ-\\r+=O=,ü0C\\x05R=\\nrSZ=[L\\x01\\nnV=Ѝ\\x19W=:w=4v=C\\x1b@<:y;\\nh=ڙ=C\\uef1e=@ے=9_S8;e<\\x1d\\x1b=rDK-S새;\\t\\x16=\\x1a\\x18~=r6\\x19=r=1?;\\x16\\r\\x18\\x1e;<\\x15j4ߜP<\\nAR\\x06=ߕ$\\x11=hgv\\x18>\\x14ѽO=Ѷ<@6=\\x03o=\\t\\x01|>A=\\x00!.c3\\\\7L\\x01==-I ];ջͣ<[\\x15\\x0cҩ=Q\\x19Rk$\\x17Oc\\x11B}j\\x02\\roy=~=4==\\r-=(=Zҹ<`@j\\x1c(\\x1b=\\x10=(x:h#pI=x\\u05fb\\\\<\\x1d\\x1cY|\\x0c=Aˡ?\\x18\\x0f\\x04n=?5d\\'=d3;\\x06`ܻ\\x101=^)\\x0c\\x13B<\">=s\\x06=\\x08=̽|\\x1f!{=i\\x19Dm\\x192;<-ſ?[R@=|\\x0f%<\\x01ؕ4\\x13$=Ӽ\\x1c-F!ﵼ\\x01Hf{\\ue17d=\\x12TB<\\x064Ἥ\\x13:\\x11\\x1b_:2;W\\x0c=Xx;m=\\x02= <+*x=-\"P=:\\\\=k\\x0c=\\x12L42\\x15\\x17!q>s=|;\\x14\\x1eKj;>v\\x1e=!=d&=s<<\\x16<4\"\\x16\"u\\x0e>\\x0b\\x05Ɍ.kY-pض\\x12\\x19<[*\\x13=\\x1ej\\t\\x7f=]p<.\\x1f=0f~;%\\n_=?;\\x1eC\\x19W\\x04=FF<_s<;=B=վȤ\\x14r\\x00\\x0c0<\\na.t=s\\x19P$\\'%\\x19\\x05===\\x7fWE}A\\r\\r*<`\\x05=TF= ^=\\x0c0=FA;\\x17G\\x01%\\x05U%=\\x0ck5\\x08Hżb\\x17\\xbeA\\x1e\\x05\\xb9Hu\\xbfg3\\xbd$\\xcd\\xbd\\xbd\\xa1$\\xf7;\\x04\\xf5z=\\xfc\\xb4\\x8c=\\x89\\x0e\\xc6\\xbdhI\\x90\\xbd^\\x16\\xbd;z\\xe7\\x0c\\xbd\\x1b3\\xc9\\xbc\\x89\\xf8\\xbb\\xbc\\x18\\'u\\xbb>\\x8f\\xca<\\x02\\x80J=\\x0e\\xaf*=\\x8dOU\\xbd\\xcf\\xf0\\x95\\xbc \\x02\\x19=\\x19\\xf4K<\\xc5\\xc2\\t=J\\x83\\xac=\\x95\\xd7\\xb8\\xbd\\xf2\\xb5\\x9c\\xbd=\\x85\\x18=\\x94d&=03\\xf8<\\xee\\xf7\\x88<\\x80v\\xf2\\xbb9=[\\xbdG\\xac\\xee\\xbb<:A\\xbd\\xe1d\\x19\\xbd!d\\xf2\\xbb\\x1d\\xbax;\\xec;O<\\xd21,\\xbc\\xec\\xae\\xae=r\\x00-\\xbc\"\\x06\\xae\\xbdl\\xd6\\x1a=\\xc4\\xbf\\xcd=\\x19\\x150=\\xe3\\xf1\\x9d\\xbc\\xa6GK=\\xb2\\xb8 =\\xb2\\xf1I\\xbd-e\\x9e\\xbb\\xe9\\x8a\\xf7:\\x88\\xf8\\x1c=\\x7f\\xba\\xde<\\xd2n\\x16\\xbb\\xb4\\\\p\\xbb\\xd4\\xd5<<\\x89\\xa5\\xa3\\xb8\\xc79s<=4&<\\x84\\x1c\\x18<\\x18\\xd9-\\xbd\\xdf\\xe6\\x98<\\x15\\xa1N=\\xa2/\\xa5=\\x1d\\xf3\\xdd<\\x17L\\x13<\\x10\\x10\\xce\\xbac\\x9e\\xdc\\xbc\\xa68\\x05=+\\xa1\\xf5\\xbd\\x84\\x1bF\\xbd\\xa0?\\x14\\xbe\\xc4\\x8f(\\xbd\\xe6O\\x89\\xbd\\xf7\\xad\\xd4<\\xa7\\x12\\xc3=\\xaf\\x05O\\xbd\\x99\\x8ep\\xbc\\x18\\xb5\\xac\\xbc\\xc9\\x9ee\\xbdH\\x8es;$a\\xc1;\\xd9\\xfaB\\xbd\\xa8#\\xfe:\\x92\\xe6\\xf4=\\xcd\\x15*<\\x86\\xf8\\x1b=\\x01\\xfcV\\xbd\\xd3\\xd1\\r=9\\xee\\x06=\\x13u\\xba\\xbd\\xf7\\xa3\\xd6<\\x1a\\xec\\xd9;\\xb79/=\\xa4\\xc2\\x85=p\\x0b\"=\\xe1i\\xef<:\\xe8c=\\xfb2\\x08\\xbe\\xce\\x12;=OVW;V\\xa4b<\\xd0\\x9d\\xb7<\\x87r;\\xbdqz\\x91\\xbcV\\x00<\\xbd\\xfe\\x19\\xa3<\\xeaJ%\\xbc!\\xe7\\xbf\\xbb\\x7f\\x87\\x12=\\x94\\x1d\\x95=b|\\xfd\\xbc\\xf3\\xf1\\xd1\\xbd\\xf5y\\x84;\\xc9\\tu=]\\x8ai<3\\x91R\\xbd\\xec\\xf3m\\xbd\\x93\\xb83=V\\xedF=\\x1f\\xf3\\xd1\\x08yA\\xba<#\\xacO\\xbd\\x01\\x0f\\xc7;\\x7f\\xf4\\x04\\xbdP\\x82\\x92\\xbd\\x9b\\xddD=p\\xd8;\\xbc\\xd3;\\xf4\\xbc\\xb3\\x8f\\x97\\xbd1\\\\\\r\\xbd\\xea\\x8c\\xf5\\xbd\\x8c\\x13(=\\x9e\\xc8\\xc6=\\xa3\\xed\\x1a=\\x98\\xa8\\xf8=\\x84\\xc1\\xee\\xbc\\xcd-\\x18\\xbb\\xf5~;<\\xd6F\\t\\xbd\\x14\\x08\\x17=\\xa5\\xa5\\x1e=\\x14K\\xcb\\xbd.\\xf7\\x8c\\xbdyb\\xed\\xbb\\x86[\\x19\\xbc]\\x0c\\x13\\xbcgq\\x83=\\xf0wd\\xbd\\xe3\\xc7\\xd1\\xbb8lY\\xbc\\xa7|a=3\\xcf\\xfd\\xbc\\x1f\\xa5\\x83\\xbb\\x99O\\x19\\xbd6\\x02]\\xbd\\xbb\\xeaz=\\x036\\x9c=:^\\xa9\\xbd)^9\\xbcg\\xe4N\\xbcs\\x07x\\xbd\\x18{\\xa0=:\\x9f\\x96<\\xecq8\\xba\\x9e\\xbb=\\xbd\\xe4|(<\\x96\\xdf\\xb4\\xbbl\\xc9\\x0b\\xbd\\xc4\\x01\\x95\\xbd\\xf7\\xc6T=\\tp\\xd1\\x17\\xbe\\x02\\x1a\\x05\\xb9@u\\xbf<\\xd6\\xe2b\\xba\\xd0\\xa6\\xa8\\xbdo\\xdc\\xec\\xbcQc%=N\\xe7r\\xbb\\x1dOG==(\\x85=y@\\xa2\\xbc7Z\\xd0\\xbdB%K\\xbd\\xba\\xed\\x94\\xbcU\\xddH=\\xbe&F<\\xbc*\\xec<\\x8c\\xd8\\x8d\\xbd\\xf3Z\\x98<\\x15\\xa3\\xa3=3g3\\xbd$\\xcd\\xbd\\xbd\\xf7$\\xf7;\\xf6\\xf4z=\\x02\\xb5\\x8c=\\x8d\\x0e\\xc6\\xbdhI\\x90\\xbdq\\x16\\xbd;u\\xe7\\x0c\\xbd&3\\xc9\\xbc\\x82\\xf8\\xbb\\xbc\\xa7&u\\xbb-\\x8f\\xca<\\xf2\\x7fJ=\\x14\\xaf*=\\x87OU\\xbd\\xde\\xf0\\x95\\xbc \\x02\\x19=\\x1b\\xf4K<\\xd0\\xc2\\t=F\\x83\\xac=\\x9e\\xd7\\xb8\\xbd\\xf3\\xb5\\x9c\\xbdB\\x85\\x18=\\xa4d&=\\'3\\xf8<\\xd3\\xf7\\x88\\xbd\\x7f\\x1bF\\xbd\\x9f?\\x14\\xbe\\xc9\\x8f(\\xbd\\xe4O\\x89\\xbd\\x18\\xae\\xd4<\\xb2\\x12\\xc3=\\xb0\\x05O\\xbd\\x8f\\x8ep\\xbc\\x1a\\xb5\\xac\\xbc\\xcc\\x9ee\\xbdv\\x8es;\\x0ca\\xc1;\\xd5\\xfaB\\xbde%\\xfe:\\x99\\xe6\\xf4=\\xa7\\x15*<\\x8c\\xf8\\x1b=\\x08\\xfcV\\xbd\\xce\\xd1\\r=<\\xee\\x06=\\x17u\\xba\\xbd\\r\\xa4\\xd6<\\x12\\xec\\xd9;\\xc89/=\\xa6\\xc2\\x85=x\\x0b\"=\\xe3i\\xef<4\\xe8c=\\xfc2\\x08\\xbe\\xd2\\x12;=\\x98VW;N\\xa4b<\\xe8\\x9d\\xb7<\\x90r;\\xbd\\\\z\\x91\\xbcO\\x00<\\xbd\\x13\\x1a\\xa3<\\x05K%\\xbcc\\xe7\\xbf\\xbb\\x89\\x87\\x12=\\x95\\x1d\\x95=||\\xfd\\xbc\\xf2\\xf1\\xd1\\xbdKz\\x84;\\xc7\\tu=.\\x8ai<=\\x91R\\xbd\\xdd\\xf3m\\xbd\\x8c\\xb83=_\\xedF=\\x1a\\xf3\\xd1\\x08oA\\xba<(\\xacO\\xbd\\xfc\\x0e\\xc7;\\x87\\xf4\\x04\\xbdN\\x82\\x92\\xbd\\x92\\xddD=a\\xd8;\\xbc\\xd1;\\xf4\\xbc\\xb2\\x8f\\x97\\xbd<\\\\\\r\\xbd\\xe1\\x8c\\xf5\\xbd\\x95\\x13(=\\xa2\\xc8\\xc6=\\xa9\\xed\\x1a=\\x98\\xa8\\xf8=\\x96\\xc1\\xee\\xbc\\xff.\\x18\\xbb\\xbf~;<\\xd9F\\t\\xbd\\x13\\x08\\x17=\\xa8\\xa5\\x1e=\\x17K\\xcb\\xbd0\\xf7\\x8c\\xbdXb\\xed\\xbb\\xc9[\\x19\\xbcU\\x0c\\x13\\xbcdq\\x83=\\xe9wd\\xbd.\\xc7\\xd1\\xbb~lY\\xbc\\xa2|a=a\\xcf\\xfd\\xbcB\\xa5\\x83\\xbb\\x9fO\\x19\\xbd&\\x02]\\xbd\\xb6\\xeaz=\\xff5\\x9c=1^\\xa9\\xbdi^9\\xbcT\\xe4N\\xbc}\\x07x\\xbd\\x17{\\xa0=@\\x9f\\x96<\\x81s8\\xba\\xa6\\xbb=\\xbd\\xb2|(<\\xc1\\xdf\\xb4\\xbbr\\xc9\\x0b\\xbd\\xc2\\x01\\x95\\xbd\\x02\\xc7T=\\x11p\\xd1\\x0c\\xb1\\xbch\\x01J\\xbda\\xf4~==\\xe3Z\\xbd?/\\xf1\\xbbJ98=\\xd92T\\xbc.\\'\\x81<\\xbd\\xa0M=\\xa0\\xde\\x05<\\x1bI|\\xbd\\xc4\\x98w<\\xdf\\xd3\\xa7\\xbd\\xdbS \\xbdl\\x13\\x07=\\x18&\\x14\\xbc\\xbev\\xe9<\\xfa,\\x97='}]" ] }, - "execution_count": 12, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -228,7 +228,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -276,35 +276,35 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "['movie:01JSMB5A6P9YKM879258RXTBPE',\n", - " 'movie:01JSMB5A6SXGGXZZQDHHCHXNM0',\n", - " 'movie:01JSMB5A6SSBTV9PJ2NWNCFJMN',\n", - " 'movie:01JSMB5A6S1C78P19Z8T2S3DT9',\n", - " 'movie:01JSMB5A6SKX1CWPSZ54C1XFW8',\n", - " 'movie:01JSMB5A6SXKZMD6SMJD1PRB6B',\n", - " 'movie:01JSMB5A6SXEMXR974JM56T09P',\n", - " 'movie:01JSMB5A6S5BKM6KQ96AHN40KA',\n", - " 'movie:01JSMB5A6SRM793TJA2Z90XKT3',\n", - " 'movie:01JSMB5A6TN3J2SYK24063ZN2X',\n", - " 'movie:01JSMB5A6TC2CYW8EPQJRRQS9P',\n", - " 'movie:01JSMB5A6TXQSX0ZPDRJZ76JDH',\n", - " 'movie:01JSMB5A6TVAJ1DQ17M917EYDB',\n", - " 'movie:01JSMB5A6TWMPD4311VTWGD393',\n", - " 'movie:01JSMB5A6T3E21MV0MKMD9KSV1',\n", - " 'movie:01JSMB5A6TVQY3JJHEBF2PRJGZ',\n", - " 'movie:01JSMB5A6THCGY2WXXP2HD4S1A',\n", - " 'movie:01JSMB5A6TEBRRM051XV4SGC20',\n", - " 'movie:01JSMB5A6TDHS799WVJ1NR35MQ',\n", - " 'movie:01JSMB5A6TDFSA582Z2831QTB3']" + "['movie:01JR6XHSRXW6DF4TSF7N2KJD21',\n", + " 'movie:01JR6XHSS0HK3E95HDVE1D5Y4W',\n", + " 'movie:01JR6XHSS0EE89YNT702SB1ZZN',\n", + " 'movie:01JR6XHSS09BNDBRZHA6F5RT0H',\n", + " 'movie:01JR6XHSS0N8W3M4YDR45HHCPY',\n", + " 'movie:01JR6XHSS1XDQFJXHHJD9Z0AW3',\n", + " 'movie:01JR6XHSS17RNERVEQ9YAHA81D',\n", + " 'movie:01JR6XHSS182SYE6E630Y6D6B1',\n", + " 'movie:01JR6XHSS1899GWQDBWHP0Q57A',\n", + " 'movie:01JR6XHSS1WRCF39MX0XQ60PEJ',\n", + " 'movie:01JR6XHSS1K9RYSRJTTNRQQP5C',\n", + " 'movie:01JR6XHSS148EGMV6JTECWRC5J',\n", + " 'movie:01JR6XHSS1199WGN103VB7GGHE',\n", + " 'movie:01JR6XHSS12RTJR8B953SDWC1E',\n", + " 'movie:01JR6XHSS1WR63V3MZNVZ5X82R',\n", + " 'movie:01JR6XHSS2Z1F2C0ZG60FCJ36F',\n", + " 'movie:01JR6XHSS250RZBG2M3C3VKWE2',\n", + " 'movie:01JR6XHSS2ECNNK19FRAZ00RE6',\n", + " 'movie:01JR6XHSS2W46EMH9EVC42TBVV',\n", + " 'movie:01JR6XHSS2K8KF6DK6MZN65MT8']" ] }, - "execution_count": 14, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -337,7 +337,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ @@ -363,30 +363,30 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "[{'vector_distance': '0.376072943211',\n", + "[{'vector_distance': '0.645975470543',\n", + " 'title': 'The Incredibles',\n", + " 'vector_similarity': '0.677012264729',\n", + " 'text_score': '10.5386477145',\n", + " 'hybrid_score': '3.63550289966'},\n", + " {'vector_distance': '0.797545194626',\n", " 'title': 'Skyfall',\n", - " 'vector_similarity': '0.811963528395',\n", - " 'text_score': '8.81509517149',\n", - " 'hybrid_score': '3.21290302132'},\n", - " {'vector_distance': '0.717951893806',\n", - " 'title': 'Fast & Furious 9',\n", - " 'vector_similarity': '0.641024053097',\n", - " 'text_score': '0',\n", - " 'hybrid_score': '0.448716837168'},\n", - " {'vector_distance': '0.750144720078',\n", - " 'title': 'Despicable Me',\n", - " 'vector_similarity': '0.624927639961',\n", - " 'text_score': '0',\n", - " 'hybrid_score': '0.437449347973'}]" + " 'vector_similarity': '0.601227402687',\n", + " 'text_score': '4.73920856087',\n", + " 'hybrid_score': '1.84262175014'},\n", + " {'vector_distance': '0.608649492264',\n", + " 'title': 'Explosive Pursuit',\n", + " 'vector_similarity': '0.695675253868',\n", + " 'text_score': '3.93239518818',\n", + " 'hybrid_score': '1.66669123416'}]" ] }, - "execution_count": 18, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -394,7 +394,7 @@ "source": [ "from redisvl.query import HybridQuery\n", "\n", - "vector = model.embed(user_query, as_buffer=True)\n", + "vector = model.embed(user_query, as_buffer=True, dtype=\"float32\")\n", "\n", "query = HybridQuery(\n", " text=user_query,\n", @@ -421,7 +421,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": {}, "outputs": [ { @@ -451,7 +451,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -471,7 +471,7 @@ "french_film_query = HybridQuery(\n", " text=french_query_text,\n", " text_field_name=\"description\",\n", - " vector=model.embed(french_query_text, as_buffer=True),\n", + " vector=model.embed(french_query_text, as_buffer=True, dtype=\"float32\"),\n", " vector_field_name=\"description_vector\",\n", " stopwords=\"french\",\n", ")\n", @@ -527,7 +527,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": {}, "outputs": [ { @@ -588,7 +588,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ @@ -616,7 +616,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": {}, "outputs": [ { @@ -651,7 +651,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 21, "metadata": {}, "outputs": [], "source": [ @@ -661,7 +661,7 @@ "\n", "def make_vector_query(user_query: str, num_results: int, filters = None) -> VectorQuery:\n", " \"\"\"Generate a Redis vector query given user query string.\"\"\"\n", - " vector = model.embed(user_query, as_buffer=True)\n", + " vector = model.embed(user_query, as_buffer=True, dtype=\"float32\")\n", " query = VectorQuery(\n", " vector=vector,\n", " vector_field_name=\"description_vector\",\n", @@ -686,7 +686,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 22, "metadata": {}, "outputs": [], "source": [ @@ -720,7 +720,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 23, "metadata": {}, "outputs": [ { @@ -753,7 +753,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 24, "metadata": {}, "outputs": [ { @@ -787,7 +787,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 25, "metadata": {}, "outputs": [], "source": [ @@ -836,7 +836,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 26, "metadata": {}, "outputs": [ { @@ -878,7 +878,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 27, "metadata": {}, "outputs": [], "source": [ @@ -903,7 +903,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 28, "metadata": {}, "outputs": [], "source": [ @@ -933,7 +933,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 29, "metadata": {}, "outputs": [], "source": [ @@ -951,7 +951,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 30, "metadata": {}, "outputs": [], "source": [ @@ -964,7 +964,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 31, "metadata": {}, "outputs": [ { @@ -1075,7 +1075,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 32, "metadata": {}, "outputs": [ { @@ -1117,7 +1117,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "redis-ai-res", "language": "python", "name": "python3" }, @@ -1131,7 +1131,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.9" + "version": "3.13.2" } }, "nbformat": 4, From 0ea90e1987d063657a83843359c4f9781f00a66a Mon Sep 17 00:00:00 2001 From: Robert Shelton Date: Thu, 1 May 2025 14:33:16 -0400 Subject: [PATCH 07/10] python version thing --- .python-version | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .python-version diff --git a/.python-version b/.python-version deleted file mode 100644 index 2419ad5b..00000000 --- a/.python-version +++ /dev/null @@ -1 +0,0 @@ -3.11.9 From ed1a648492cf39e540296487e305da4646bffde0 Mon Sep 17 00:00:00 2001 From: Robert Shelton Date: Thu, 1 May 2025 14:57:11 -0400 Subject: [PATCH 08/10] python version thing --- python-recipes/vector-search/00_redispy.ipynb | 69 +++++++++++-------- 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/python-recipes/vector-search/00_redispy.ipynb b/python-recipes/vector-search/00_redispy.ipynb index 9d49ee85..b28f0b87 100644 --- a/python-recipes/vector-search/00_redispy.ipynb +++ b/python-recipes/vector-search/00_redispy.ipynb @@ -148,7 +148,7 @@ }, { "cell_type": "code", - "execution_count": 57, + "execution_count": 1, "id": "aefda1d1", "metadata": {}, "outputs": [], @@ -174,7 +174,7 @@ }, { "cell_type": "code", - "execution_count": 58, + "execution_count": 2, "id": "370c1fcc", "metadata": {}, "outputs": [ @@ -184,7 +184,7 @@ "True" ] }, - "execution_count": 58, + "execution_count": 2, "metadata": {}, "output_type": "execute_result" } @@ -197,7 +197,7 @@ }, { "cell_type": "code", - "execution_count": 59, + "execution_count": 3, "id": "458fc773", "metadata": {}, "outputs": [], @@ -210,10 +210,21 @@ }, { "cell_type": "code", - "execution_count": 60, + "execution_count": 4, "id": "8d561462", "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": [ "import numpy as np\n", "from sentence_transformers import SentenceTransformer\n", @@ -227,7 +238,7 @@ }, { "cell_type": "code", - "execution_count": 61, + "execution_count": 5, "id": "9946a382", "metadata": {}, "outputs": [], @@ -243,7 +254,7 @@ }, { "cell_type": "code", - "execution_count": 62, + "execution_count": 6, "id": "8797fcc6", "metadata": {}, "outputs": [ @@ -258,7 +269,7 @@ " 'vector': b'\\x8bf|=\\xc3`\\n;\\xf2\\x91\\xb7;?\\xcb~\\xbd\\xdfd\\xce\\xbb\\xc7\\x16J=H\\xa7?=\\xdfv\\x95\\x17\\xbeA\\x1e\\x05\\xb9Hu\\xbfg3\\xbd$\\xcd\\xbd\\xbd\\xa1$\\xf7;\\x04\\xf5z=\\xfc\\xb4\\x8c=\\x89\\x0e\\xc6\\xbdhI\\x90\\xbd^\\x16\\xbd;z\\xe7\\x0c\\xbd\\x1b3\\xc9\\xbc\\x89\\xf8\\xbb\\xbc\\x18\\'u\\xbb>\\x8f\\xca<\\x02\\x80J=\\x0e\\xaf*=\\x8dOU\\xbd\\xcf\\xf0\\x95\\xbc \\x02\\x19=\\x19\\xf4K<\\xc5\\xc2\\t=J\\x83\\xac=\\x95\\xd7\\xb8\\xbd\\xf2\\xb5\\x9c\\xbd=\\x85\\x18=\\x94d&=03\\xf8<\\xee\\xf7\\x88<\\x80v\\xf2\\xbb9=[\\xbdG\\xac\\xee\\xbb<:A\\xbd\\xe1d\\x19\\xbd!d\\xf2\\xbb\\x1d\\xbax;\\xec;O<\\xd21,\\xbc\\xec\\xae\\xae=r\\x00-\\xbc\"\\x06\\xae\\xbdl\\xd6\\x1a=\\xc4\\xbf\\xcd=\\x19\\x150=\\xe3\\xf1\\x9d\\xbc\\xa6GK=\\xb2\\xb8 =\\xb2\\xf1I\\xbd-e\\x9e\\xbb\\xe9\\x8a\\xf7:\\x88\\xf8\\x1c=\\x7f\\xba\\xde<\\xd2n\\x16\\xbb\\xb4\\\\p\\xbb\\xd4\\xd5<<\\x89\\xa5\\xa3\\xb8\\xc79s<=4&<\\x84\\x1c\\x18<\\x18\\xd9-\\xbd\\xdf\\xe6\\x98<\\x15\\xa1N=\\xa2/\\xa5=\\x1d\\xf3\\xdd<\\x17L\\x13<\\x10\\x10\\xce\\xbac\\x9e\\xdc\\xbc\\xa68\\x05=+\\xa1\\xf5\\xbd\\x84\\x1bF\\xbd\\xa0?\\x14\\xbe\\xc4\\x8f(\\xbd\\xe6O\\x89\\xbd\\xf7\\xad\\xd4<\\xa7\\x12\\xc3=\\xaf\\x05O\\xbd\\x99\\x8ep\\xbc\\x18\\xb5\\xac\\xbc\\xc9\\x9ee\\xbdH\\x8es;$a\\xc1;\\xd9\\xfaB\\xbd\\xa8#\\xfe:\\x92\\xe6\\xf4=\\xcd\\x15*<\\x86\\xf8\\x1b=\\x01\\xfcV\\xbd\\xd3\\xd1\\r=9\\xee\\x06=\\x13u\\xba\\xbd\\xf7\\xa3\\xd6<\\x1a\\xec\\xd9;\\xb79/=\\xa4\\xc2\\x85=p\\x0b\"=\\xe1i\\xef<:\\xe8c=\\xfb2\\x08\\xbe\\xce\\x12;=OVW;V\\xa4b<\\xd0\\x9d\\xb7<\\x87r;\\xbdqz\\x91\\xbcV\\x00<\\xbd\\xfe\\x19\\xa3<\\xeaJ%\\xbc!\\xe7\\xbf\\xbb\\x7f\\x87\\x12=\\x94\\x1d\\x95=b|\\xfd\\xbc\\xf3\\xf1\\xd1\\xbd\\xf5y\\x84;\\xc9\\tu=]\\x8ai<3\\x91R\\xbd\\xec\\xf3m\\xbd\\x93\\xb83=V\\xedF=\\x1f\\xf3\\xd1\\x08yA\\xba<#\\xacO\\xbd\\x01\\x0f\\xc7;\\x7f\\xf4\\x04\\xbdP\\x82\\x92\\xbd\\x9b\\xddD=p\\xd8;\\xbc\\xd3;\\xf4\\xbc\\xb3\\x8f\\x97\\xbd1\\\\\\r\\xbd\\xea\\x8c\\xf5\\xbd\\x8c\\x13(=\\x9e\\xc8\\xc6=\\xa3\\xed\\x1a=\\x98\\xa8\\xf8=\\x84\\xc1\\xee\\xbc\\xcd-\\x18\\xbb\\xf5~;<\\xd6F\\t\\xbd\\x14\\x08\\x17=\\xa5\\xa5\\x1e=\\x14K\\xcb\\xbd.\\xf7\\x8c\\xbdyb\\xed\\xbb\\x86[\\x19\\xbc]\\x0c\\x13\\xbcgq\\x83=\\xf0wd\\xbd\\xe3\\xc7\\xd1\\xbb8lY\\xbc\\xa7|a=3\\xcf\\xfd\\xbc\\x1f\\xa5\\x83\\xbb\\x99O\\x19\\xbd6\\x02]\\xbd\\xbb\\xeaz=\\x036\\x9c=:^\\xa9\\xbd)^9\\xbcg\\xe4N\\xbcs\\x07x\\xbd\\x18{\\xa0=:\\x9f\\x96<\\xecq8\\xba\\x9e\\xbb=\\xbd\\xe4|(<\\x96\\xdf\\xb4\\xbbl\\xc9\\x0b\\xbd\\xc4\\x01\\x95\\xbd\\xf7\\xc6T=\\tp\\xd1\\x17A\\x1e\\x05Hug3$ͽ$;\\x04z==\\x0eƽhI^\\x16;z\\x0c\\x1b3ɼ\\x18\\'u><\\x02J=\\x0e*=OU \\x02\\x19=\\x19K<\\t=J=\\u05f8\\U000b573d=\\x18=d&=03<\\x1bF?\\x14ď(O<\\x12=\\x05Op\\x18ɞeHs;$a;B#:=\\x15*<\\x1b=\\x01V\\r=9\\x06=\\x13u<\\x1a;9/=\\x85=p\\x0b\"=i<:c=2\\x08\\x12;=OVW;Vb<Н<9,=\\x17ߺ\\x14:M9\\x08\\x0bV<_6=!Ub#=WX=u\\x11=?6=\\x06,<\\'\\x15t=;лwK-=H\\x11\\x036=\\x15<8xM\\x10=_\\x03D=\\x0b\\x08$G\\x0cr=m=<)$y\\x06=X=s%\\r\\x1dz\\x0e\\t<$\\tI=\\x01x\\x10;Y\\x0f<蓻bߺe c=>;\\x18u༎\\x10x~=ah<\\x070;#r=iD:?ئa2g\\x00=\\x1bą;g\\x12=OʃRF2=\\x11䛽%==^<̒\\x06=-@g<;ܼX\\x19=#b\\x0bb}xU;\\\\\\x08~=/&N(缸&\\x08ۆ=:p^<|僼½f\\x11=\\u05fdx<#;Ȼ=1I\\x0b\\x7f\\x0cR\\x11\\x14ʽuA<;\\rpr}\\x0f\\x18=Tp1gC<:\\x16{\\x19.<$5=AGl=-\\\\=hGEY>;2\\r==y{@\\x16Oƻ$o=\\x0b#j=~0> {\\x03kl/=ul\\x07ͼ\\x17>F1\\x1bYFؔ/\\x1d5M\\x07Jݏ=-\\x08xN>\\x7f;M\\x05u\\x19H@tC=<\\x0f\\x18Kz=\\x13=ጽ&=qZ\\x07=Mq=^ߣA*\\'\\x13\\x03=;A&s=u0ltn>\\t=bڼ@f\\'j\\x10\\x01=Ѽ\\x12C=6)vgi6\\x05\\x01l\\x15<\\x17m\\x15; =\\rL\\x13;ýC=\\x04лS\\x03_\\x02[=B/D>=5\\x19\\x03\\x13<\\r|K=\\'h<\\nB<>9T\\x1eh=ݨa=Ϳ-\\x00;=fK=t=}ظ;Ϧj<ݛ;\\x03}<-<\\x18;\\x1e.=\\x1en;\\x01G=L\\x10Q\\\\|\\x11Yo=u\\x0f\\x19%+=1P<:m;\\x07&==rQA\\x15ϼ\\x0b+<\\x02=h\\x0e9=I3K=5ͼ\\x04E7;ty|=\\x04Ӏ<\\x0c<\\x01\\x0e\\x18>\\x0f\\x14qiQ=yR:kX=\\x13|\\x0b=ǎI0s-Qߒ;{XB=\\r\\x046=y6EW=\\r<=X=\\x1a<\\x18U\\x15\\x02I\\x00Bg;~ =\\x7fv\\x16y\\'غ\\x19\\r\\x1b)(3\\x16Oj\\x0eA0=7L=dI\\r=A[=\\x02A;\\\\=o\\x00Ƽ)V¼Їh5\\x01=\\x06=h>ˠŐWxL=\\x04=v\\x7f)͓:\\x10;aZ\"\\x06/2\\x0b==\\t/&|f<ӽm\\x1fnx=+F\\n*<}w\\x07lI\\x00\\x02@=Bi\\x06=\\x1c\\x11v:/ٍ!\\x18(Ј`;<ᓟ\\x02R=\\x13>c{R=3Qٽ2ӄ\\x05<~<${Y=_i=Ib>=Y\\x1c<̠$>#=\\x01j|\\x19Q=6l=\\x15q-Sf<\\x1d\\x07$=\\x1f\\x0e=>\\x03$L~<\\x01\\x02a\\x1dI<\\x14=ZnS3m!~͈\\x05\\u07bb\\x1e=cHf\\x11h@<1ki$3=\\x14\\x08.\\x17w>=\\x03)=><\\x1d\\x10b괺Be=\\x1b\\x003=Y<\\x156e<1bL=D\\x03\\x0b]b\\x14<3 >\\x02\\n:2*=\"8,QʽQ=j\\x1d\\x16w!>\\x13<\\x1ey!\\x00U<\\x13u<\\x12<\\x14C[:c=5<@\\x0bM=\\x05\\x182;f<ӭ==\\x03b;\\x0bН<\\x1b=\\r\\tșL[{\\x16;!μU;\\nZ<\\x0f\\x17=ߑ=\\uec09dT=^Լ<\\x0c;\\x196(=\\x08\\x1b<\\x01=!\\x17<\\x0f.=yq=~\\x1a\\x1f:G0(H]X=d\\x10=Ge@[\\x06F<', 'title': 'John Wick', 'rating': '8'}, Document {'id': '6', 'payload': None, 'genre': 'action', 'description': 'Batman faces off against the Joker, a criminal mastermind who threatens to plunge Gotham into chaos.', 'vector': ':A%=Em5\\x0eGh=\\x035%\\x01P\\x1eq\\x1d\\x1c=N==\\r\\x04\\\\8E= ,==4\\x01G==(<\\x02/)=PK6\\x04Y螉\\x0eྲྀ8:2jt|=,\\x0c6\\x17am<&=\\t\\x18>_\\x108<\\x0f!lQ^\\x0e>1K=<*F\\x01Q.hЌg\\r\\x01<Ԭ<@<0\\r\\x11=\\rq\\rT\\'P=y\\x17ml>DM}=rH5=\\x0f\\x13Ϋ=D\\x03;\\rR=a=4=\\x13q\\x07=ޭ\\x01=\\x17<.J\\x01=Gy\\t\\x13S=\\'6k\\x00\\x07;Oؽf\\x08<2ݼ<(}E=M{JֽY=Vj\\x18A=CT@]=Jj<18\\x1a=ぎ=\\r8P{<.4Ž\\x0f=\\\\g==+D=Vce=6xUǽ-\\r+=O=,ü0C\\x05R=\\nrSZ=[L\\x01\\nnV=Ѝ\\x19W=:w=4v=C\\x1b@<:y;\\nh=ڙ=C\\uef1e=@ے=9_S8;e<\\x1d\\x1b=rDK-S새;\\t\\x16=\\x1a\\x18~=r6\\x19=r=1?;\\x16\\r\\x18\\x1e;<\\x15j4ߜP<\\nAR\\x06=ߕ$\\x11=hgv\\x18>\\x14ѽO=Ѷ<@6=\\x03o=\\t\\x01|>A=\\x00!.c3\\\\7L\\x01==-I ];ջͣ<[\\x15\\x0cҩ=Q\\x19Rk$\\x17Oc\\x11B}j\\x02\\roy=~=4==\\r-=(=Zҹ<`@j\\x1c(\\x1b=\\x10=(x:h#pI=x\\u05fb\\\\<\\x1d\\x1cY|\\x0c=Aˡ?\\x18\\x0f\\x04n=?5d\\'=d3;\\x06`ܻ\\x101=^)\\x0c\\x13B<\">=s\\x06=\\x08=̽|\\x1f!{=i\\x19Dm\\x192;<-ſ?[R@=|\\x0f%<\\x01ؕ4\\x13$=Ӽ\\x1c-F!ﵼ\\x01Hf{\\ue17d=\\x12TB<\\x064Ἥ\\x13:\\x11\\x1b_:2;W\\x0c=Xx;m=\\x02= <+*x=-\"P=:\\\\=k\\x0c=\\x12L42\\x15\\x17!q>s=|;\\x14\\x1eKj;>v\\x1e=!=d&=s<<\\x16<4\"\\x16\"u\\x0e>\\x0b\\x05Ɍ.kY-pض\\x12\\x19<[*\\x13=\\x1ej\\t\\x7f=]p<.\\x1f=0f~;%\\n_=?;\\x1eC\\x19W\\x04=FF<_s<;=B=վȤ\\x14r\\x00\\x0c0<\\na.t=s\\x19P$\\'%\\x19\\x05===\\x7fWE}A\\r\\r*<`\\x05=TF= ^=\\x0c0=FA;\\x17G\\x01%\\x05U%=\\x0ck5\\x08Hżb Date: Thu, 1 May 2025 15:14:46 -0400 Subject: [PATCH 09/10] update redisvl pins --- .../02_semantic_cache_optimization.ipynb | 3 +- .../semantic-router/00_semantic_routing.ipynb | 4 +- .../01_routing_optimization.ipynb | 53 +------------------ 3 files changed, 4 insertions(+), 56 deletions(-) diff --git a/python-recipes/semantic-cache/02_semantic_cache_optimization.ipynb b/python-recipes/semantic-cache/02_semantic_cache_optimization.ipynb index 3a3054a8..f7933d63 100644 --- a/python-recipes/semantic-cache/02_semantic_cache_optimization.ipynb +++ b/python-recipes/semantic-cache/02_semantic_cache_optimization.ipynb @@ -26,8 +26,7 @@ "metadata": {}, "outputs": [], "source": [ - "# install from branch since scheduled for 0.5.0\n", - "%pip install git+https://github.com/redis/redis-vl-python.git@0.5.0" + "%pip install \"redisvl>=0.6.0\"" ] }, { diff --git a/python-recipes/semantic-router/00_semantic_routing.ipynb b/python-recipes/semantic-router/00_semantic_routing.ipynb index cdf57fbc..981e8783 100644 --- a/python-recipes/semantic-router/00_semantic_routing.ipynb +++ b/python-recipes/semantic-router/00_semantic_routing.ipynb @@ -29,7 +29,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "c620286e", "metadata": {}, "outputs": [ @@ -42,7 +42,7 @@ } ], "source": [ - "%pip install -q \"redisvl>=0.4.1\" sentence-transformers" + "%pip install -q \"redisvl>=0.6.0\" sentence-transformers" ] }, { diff --git a/python-recipes/semantic-router/01_routing_optimization.ipynb b/python-recipes/semantic-router/01_routing_optimization.ipynb index db770c70..2c366ba1 100644 --- a/python-recipes/semantic-router/01_routing_optimization.ipynb +++ b/python-recipes/semantic-router/01_routing_optimization.ipynb @@ -44,58 +44,7 @@ } ], "source": [ - "%pip install -q sentence-transformers ranx" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "717284f0", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Collecting git+https://github.com/redis/redis-vl-python.git@0.5.0\n", - " Cloning https://github.com/redis/redis-vl-python.git (to revision 0.5.0) to /private/var/folders/_g/rr4lnxxx1_z7m78lz89dhvsm0000gp/T/pip-req-build-54zjmrpr\n", - " Running command git clone --filter=blob:none --quiet https://github.com/redis/redis-vl-python.git /private/var/folders/_g/rr4lnxxx1_z7m78lz89dhvsm0000gp/T/pip-req-build-54zjmrpr\n", - " Running command git checkout -b 0.5.0 --track origin/0.5.0\n", - " Switched to a new branch '0.5.0'\n", - " branch '0.5.0' set up to track 'origin/0.5.0'.\n", - " Resolved https://github.com/redis/redis-vl-python.git to commit 3ca4c97baa9640d24feedd3bb3791cf95859367d\n", - " Installing build dependencies ... \u001b[?25ldone\n", - "\u001b[?25h Getting requirements to build wheel ... \u001b[?25ldone\n", - "\u001b[?25h Preparing metadata (pyproject.toml) ... \u001b[?25ldone\n", - "\u001b[?25hRequirement already satisfied: coloredlogs<16.0,>=15.0 in /Users/robert.shelton/.pyenv/versions/3.11.8/lib/python3.11/site-packages (from redisvl==0.4.1) (15.0.1)\n", - "Requirement already satisfied: ml-dtypes<0.5.0,>=0.4.0 in /Users/robert.shelton/.pyenv/versions/3.11.8/lib/python3.11/site-packages (from redisvl==0.4.1) (0.4.1)\n", - "Requirement already satisfied: numpy<2,>=1 in /Users/robert.shelton/.pyenv/versions/3.11.8/lib/python3.11/site-packages (from redisvl==0.4.1) (1.26.4)\n", - "Requirement already satisfied: pydantic<3,>=2 in /Users/robert.shelton/.pyenv/versions/3.11.8/lib/python3.11/site-packages (from redisvl==0.4.1) (2.7.4)\n", - "Requirement already satisfied: python-ulid<4.0.0,>=3.0.0 in /Users/robert.shelton/.pyenv/versions/3.11.8/lib/python3.11/site-packages (from redisvl==0.4.1) (3.0.0)\n", - "Requirement already satisfied: pyyaml<7.0,>=5.4 in /Users/robert.shelton/.pyenv/versions/3.11.8/lib/python3.11/site-packages (from redisvl==0.4.1) (6.0.1)\n", - "Requirement already satisfied: redis<6.0,>=5.0 in /Users/robert.shelton/.pyenv/versions/3.11.8/lib/python3.11/site-packages (from redisvl==0.4.1) (5.0.5)\n", - "Requirement already satisfied: tabulate<0.10.0,>=0.9.0 in /Users/robert.shelton/.pyenv/versions/3.11.8/lib/python3.11/site-packages (from redisvl==0.4.1) (0.9.0)\n", - "Requirement already satisfied: tenacity>=8.2.2 in /Users/robert.shelton/.pyenv/versions/3.11.8/lib/python3.11/site-packages (from redisvl==0.4.1) (8.3.0)\n", - "Requirement already satisfied: humanfriendly>=9.1 in /Users/robert.shelton/.pyenv/versions/3.11.8/lib/python3.11/site-packages (from coloredlogs<16.0,>=15.0->redisvl==0.4.1) (10.0)\n", - "Requirement already satisfied: annotated-types>=0.4.0 in /Users/robert.shelton/.pyenv/versions/3.11.8/lib/python3.11/site-packages (from pydantic<3,>=2->redisvl==0.4.1) (0.7.0)\n", - "Requirement already satisfied: pydantic-core==2.18.4 in /Users/robert.shelton/.pyenv/versions/3.11.8/lib/python3.11/site-packages (from pydantic<3,>=2->redisvl==0.4.1) (2.18.4)\n", - "Requirement already satisfied: typing-extensions>=4.6.1 in /Users/robert.shelton/.pyenv/versions/3.11.8/lib/python3.11/site-packages (from pydantic<3,>=2->redisvl==0.4.1) (4.12.2)\n", - "Building wheels for collected packages: redisvl\n", - " Building wheel for redisvl (pyproject.toml) ... \u001b[?25ldone\n", - "\u001b[?25h Created wheel for redisvl: filename=redisvl-0.4.1-py3-none-any.whl size=113401 sha256=973e3b34a10bf10547873947798f4c37f681a87bd1f53c7cf938f2b4bccd71a6\n", - " Stored in directory: /private/var/folders/_g/rr4lnxxx1_z7m78lz89dhvsm0000gp/T/pip-ephem-wheel-cache-wt36bttp/wheels/95/dc/1e/d8dc251e38989044675dae0b596a2dee10cbfdecac5c62ccdf\n", - "Successfully built redisvl\n", - "Installing collected packages: redisvl\n", - "Successfully installed redisvl-0.4.1\n", - "\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;49m25.0.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": [ - "%pip install git+https://github.com/redis/redis-vl-python.git@0.5.0" + "%pip install -q sentence-transformers ranx \"redisvl>=0.6.0\"" ] }, { From b3e733774690d804eb2230d8cc9c272c138334ef Mon Sep 17 00:00:00 2001 From: Robert Shelton Date: Thu, 1 May 2025 15:35:20 -0400 Subject: [PATCH 10/10] notebook test exec --- python-recipes/semantic-router/00_semantic_routing.ipynb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python-recipes/semantic-router/00_semantic_routing.ipynb b/python-recipes/semantic-router/00_semantic_routing.ipynb index 981e8783..5b1e0329 100644 --- a/python-recipes/semantic-router/00_semantic_routing.ipynb +++ b/python-recipes/semantic-router/00_semantic_routing.ipynb @@ -29,7 +29,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 26, "id": "c620286e", "metadata": {}, "outputs": [ @@ -37,6 +37,9 @@ "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;49m25.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" ] }