{
  "id": "hybrid_queries",
  "title": "Querying with RedisVL",
  "url": "https://redis.io/docs/latest/develop/ai/redisvl/0.13.2/user_guide/hybrid_queries/",
  "summary": "",
  "content": "\n\nIn this notebook, we will explore more complex queries that can be performed with ``redisvl``\n\nBefore running this notebook, be sure to\n1. Have installed ``redisvl`` and have that environment active for this notebook.\n2. Have a running Redis instance with RediSearch \u003e 2.4 running.\n\n\n```python\nimport pickle\nfrom jupyterutils import table_print, result_print\n\n# load in the example data and printing utils\ndata = pickle.load(open(\"hybrid_example_data.pkl\", \"rb\"))\ntable_print(data)\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003cth\u003euser_embedding\u003c/th\u003e\u003cth\u003elast_updated\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ejohn\u003c/td\u003e\u003ctd\u003e18\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003eb'\\xcd\\xcc\\xcc=\\xcd\\xcc\\xcc=\\x00\\x00\\x00?'\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ederrick\u003c/td\u003e\u003ctd\u003e14\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003eb'\\xcd\\xcc\\xcc=\\xcd\\xcc\\xcc=\\x00\\x00\\x00?'\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003enancy\u003c/td\u003e\u003ctd\u003e94\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003eb'333?\\xcd\\xcc\\xcc=\\x00\\x00\\x00?'\u003c/td\u003e\u003ctd\u003e1710696589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003etyler\u003c/td\u003e\u003ctd\u003e100\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003eb'\\xcd\\xcc\\xcc=\\xcd\\xcc\\xcc\u003e\\x00\\x00\\x00?'\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003etim\u003c/td\u003e\u003ctd\u003e12\u003c/td\u003e\u003ctd\u003edermatologist\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003eb'\\xcd\\xcc\\xcc\u003e\\xcd\\xcc\\xcc\u003e\\x00\\x00\\x00?'\u003c/td\u003e\u003ctd\u003e1739644189\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003etaimur\u003c/td\u003e\u003ctd\u003e15\u003c/td\u003e\u003ctd\u003eCEO\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003eb'\\x9a\\x99\\x19?\\xcd\\xcc\\xcc=\\x00\\x00\\x00?'\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ejoe\u003c/td\u003e\u003ctd\u003e35\u003c/td\u003e\u003ctd\u003edentist\u003c/td\u003e\u003ctd\u003emedium\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003eb'fff?fff?\\xcd\\xcc\\xcc='\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n\n```python\nschema = {\n    \"index\": {\n        \"name\": \"user_queries\",\n        \"prefix\": \"user_queries_docs\",\n        \"storage_type\": \"hash\", # default setting -- HASH\n    },\n    \"fields\": [\n        {\"name\": \"user\", \"type\": \"tag\"},\n        {\"name\": \"credit_score\", \"type\": \"tag\"},\n        {\"name\": \"job\", \"type\": \"text\"},\n        {\"name\": \"age\", \"type\": \"numeric\"},\n        {\"name\": \"last_updated\", \"type\": \"numeric\"},\n        {\"name\": \"office_location\", \"type\": \"geo\"},\n        {\n            \"name\": \"user_embedding\",\n            \"type\": \"vector\",\n            \"attrs\": {\n                \"dims\": 3,\n                \"distance_metric\": \"cosine\",\n                \"algorithm\": \"flat\",\n                \"datatype\": \"float32\"\n            }\n\n        }\n    ],\n}\n```\n\n\n```python\nfrom redisvl.index import SearchIndex\n\n# construct a search index from the schema\nindex = SearchIndex.from_dict(schema, redis_url=\"redis://localhost:6379\")\n\n# create the index (no data yet)\nindex.create(overwrite=True)\n```\n\n\n```python\n# use the CLI to see the created index\n!rvl index listall\n```\n\n    13:00:56 [RedisVL] INFO   Indices:\n    13:00:56 [RedisVL] INFO   1. user_queries\n\n\n\n```python\n# load data to redis\nkeys = index.load(data)\n```\n\n\n```python\nindex.info()['num_docs']\n```\n\n\n\n\n    7\n\n\n\n## Hybrid Queries\n\nHybrid queries are queries that combine multiple types of filters. For example, you may want to search for a user that is a certain age, has a certain job, and is within a certain distance of a location. This is a hybrid query that combines numeric, tag, and geographic filters.\n\n### Tag Filters\n\nTag filters are filters that are applied to tag fields. These are fields that are not tokenized and are used to store a single categorical value.\n\n\n```python\nfrom redisvl.query import VectorQuery\nfrom redisvl.query.filter import Tag\n\nt = Tag(\"credit_score\") == \"high\"\n\nv = VectorQuery(\n    vector=[0.1, 0.1, 0.5],\n    vector_field_name=\"user_embedding\",\n    return_fields=[\"user\", \"credit_score\", \"age\", \"job\", \"office_location\", \"last_updated\"],\n    filter_expression=t\n)\n\nresults = index.query(v)\nresult_print(results)\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003cth\u003elast_updated\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ejohn\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e18\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.109129190445\u003c/td\u003e\u003ctd\u003etyler\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e100\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.158808946609\u003c/td\u003e\u003ctd\u003etim\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e12\u003c/td\u003e\u003ctd\u003edermatologist\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1739644189\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.266666650772\u003c/td\u003e\u003ctd\u003enancy\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e94\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1710696589\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n\n```python\n# negation\nt = Tag(\"credit_score\") != \"high\"\n\nv.set_filter(t)\nresult_print(index.query(v))\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003cth\u003elast_updated\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ederrick\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e14\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.217882037163\u003c/td\u003e\u003ctd\u003etaimur\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e15\u003c/td\u003e\u003ctd\u003eCEO\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.653301358223\u003c/td\u003e\u003ctd\u003ejoe\u003c/td\u003e\u003ctd\u003emedium\u003c/td\u003e\u003ctd\u003e35\u003c/td\u003e\u003ctd\u003edentist\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n**Performance Tip:** For HNSW and SVS-VAMANA indexes, you can add runtime parameters to tune search performance:\n\n```python\n# Example with runtime parameters for better recall\nv = VectorQuery(\n    vector=[0.1, 0.1, 0.5],\n    vector_field_name=\"user_embedding\",\n    return_fields=[\"user\", \"credit_score\", \"age\"],\n    filter_expression=t,\n    ef_runtime=100,  # HNSW: higher for better recall\n    search_window_size=40  # SVS-VAMANA: larger window for better recall\n)\n```\n\nThese parameters can be adjusted at query time without rebuilding the index. See the [Advanced Queries guide](11_advanced_queries.ipynb) for more details.\n\n\n```python\n# use multiple tags as a list\nt = Tag(\"credit_score\") == [\"high\", \"medium\"]\n\nv.set_filter(t)\nresult_print(index.query(v))\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003cth\u003elast_updated\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ejohn\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e18\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.109129190445\u003c/td\u003e\u003ctd\u003etyler\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e100\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.158808946609\u003c/td\u003e\u003ctd\u003etim\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e12\u003c/td\u003e\u003ctd\u003edermatologist\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1739644189\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.266666650772\u003c/td\u003e\u003ctd\u003enancy\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e94\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1710696589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.653301358223\u003c/td\u003e\u003ctd\u003ejoe\u003c/td\u003e\u003ctd\u003emedium\u003c/td\u003e\u003ctd\u003e35\u003c/td\u003e\u003ctd\u003edentist\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n\n```python\n# use multiple tags as a set (to enforce uniqueness)\nt = Tag(\"credit_score\") == set([\"high\", \"high\", \"medium\"])\n\nv.set_filter(t)\nresult_print(index.query(v))\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003cth\u003elast_updated\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ejohn\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e18\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.109129190445\u003c/td\u003e\u003ctd\u003etyler\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e100\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.158808946609\u003c/td\u003e\u003ctd\u003etim\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e12\u003c/td\u003e\u003ctd\u003edermatologist\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1739644189\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.266666650772\u003c/td\u003e\u003ctd\u003enancy\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e94\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1710696589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.653301358223\u003c/td\u003e\u003ctd\u003ejoe\u003c/td\u003e\u003ctd\u003emedium\u003c/td\u003e\u003ctd\u003e35\u003c/td\u003e\u003ctd\u003edentist\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\nWhat about scenarios where you might want to dynamically generate a list of tags? Have no fear. RedisVL allows you to do this gracefully without having to check for the **empty case**. The **empty case** is when you attempt to run a Tag filter on a field with no defined values to match:\n\n`Tag(\"credit_score\") == []`\n\nAn empty filter like the one above will yield a `*` Redis query filter which implies the base case -- there is no filter here to use.\n\n\n```python\n# gracefully fallback to \"*\" filter if empty case\nempty_case = Tag(\"credit_score\") == []\n\nv.set_filter(empty_case)\nresult_print(index.query(v))\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003cth\u003elast_updated\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ejohn\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e18\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ederrick\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e14\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.109129190445\u003c/td\u003e\u003ctd\u003etyler\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e100\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.158808946609\u003c/td\u003e\u003ctd\u003etim\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e12\u003c/td\u003e\u003ctd\u003edermatologist\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1739644189\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.217882037163\u003c/td\u003e\u003ctd\u003etaimur\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e15\u003c/td\u003e\u003ctd\u003eCEO\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.266666650772\u003c/td\u003e\u003ctd\u003enancy\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e94\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1710696589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.653301358223\u003c/td\u003e\u003ctd\u003ejoe\u003c/td\u003e\u003ctd\u003emedium\u003c/td\u003e\u003ctd\u003e35\u003c/td\u003e\u003ctd\u003edentist\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n### Numeric Filters\n\nNumeric filters are filters that are applied to numeric fields and can be used to isolate a range of values for a given field.\n\n\n```python\nfrom redisvl.query.filter import Num\n\nnumeric_filter = Num(\"age\").between(15, 35)\n\nv.set_filter(numeric_filter)\nresult_print(index.query(v))\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003cth\u003elast_updated\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ejohn\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e18\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.217882037163\u003c/td\u003e\u003ctd\u003etaimur\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e15\u003c/td\u003e\u003ctd\u003eCEO\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.653301358223\u003c/td\u003e\u003ctd\u003ejoe\u003c/td\u003e\u003ctd\u003emedium\u003c/td\u003e\u003ctd\u003e35\u003c/td\u003e\u003ctd\u003edentist\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n\n```python\n# exact match query\nnumeric_filter = Num(\"age\") == 14\n\nv.set_filter(numeric_filter)\nresult_print(index.query(v))\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003cth\u003elast_updated\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ederrick\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e14\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n\n```python\n# negation\nnumeric_filter = Num(\"age\") != 14\n\nv.set_filter(numeric_filter)\nresult_print(index.query(v))\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003cth\u003elast_updated\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ejohn\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e18\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.109129190445\u003c/td\u003e\u003ctd\u003etyler\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e100\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.158808946609\u003c/td\u003e\u003ctd\u003etim\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e12\u003c/td\u003e\u003ctd\u003edermatologist\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1739644189\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.217882037163\u003c/td\u003e\u003ctd\u003etaimur\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e15\u003c/td\u003e\u003ctd\u003eCEO\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.266666650772\u003c/td\u003e\u003ctd\u003enancy\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e94\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1710696589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.653301358223\u003c/td\u003e\u003ctd\u003ejoe\u003c/td\u003e\u003ctd\u003emedium\u003c/td\u003e\u003ctd\u003e35\u003c/td\u003e\u003ctd\u003edentist\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n### Timestamp Filters\n\nIn redis all times are stored as an epoch time numeric however, this class allows you to filter with python datetime for ease of use. \n\n\n```python\nfrom redisvl.query.filter import Timestamp\nfrom datetime import datetime\n\ndt = datetime(2025, 3, 16, 13, 45, 39, 132589)\nprint(f'Epoch comparison: {dt.timestamp()}')\n\ntimestamp_filter = Timestamp(\"last_updated\") \u003e dt\n\nv.set_filter(timestamp_filter)\nresult_print(index.query(v))\n```\n\n    Epoch comparison: 1742147139.132589\n\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003cth\u003elast_updated\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.109129190445\u003c/td\u003e\u003ctd\u003etyler\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e100\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.217882037163\u003c/td\u003e\u003ctd\u003etaimur\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e15\u003c/td\u003e\u003ctd\u003eCEO\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.653301358223\u003c/td\u003e\u003ctd\u003ejoe\u003c/td\u003e\u003ctd\u003emedium\u003c/td\u003e\u003ctd\u003e35\u003c/td\u003e\u003ctd\u003edentist\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n\n```python\nfrom redisvl.query.filter import Timestamp\nfrom datetime import datetime\n\ndt = datetime(2025, 3, 16, 13, 45, 39, 132589)\n\nprint(f'Epoch comparison: {dt.timestamp()}')\n\ntimestamp_filter = Timestamp(\"last_updated\") \u003c dt\n\nv.set_filter(timestamp_filter)\nresult_print(index.query(v))\n```\n\n    Epoch comparison: 1742147139.132589\n\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003cth\u003elast_updated\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ejohn\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e18\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ederrick\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e14\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.158808946609\u003c/td\u003e\u003ctd\u003etim\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e12\u003c/td\u003e\u003ctd\u003edermatologist\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1739644189\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.266666650772\u003c/td\u003e\u003ctd\u003enancy\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e94\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1710696589\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n\n```python\nfrom redisvl.query.filter import Timestamp\nfrom datetime import datetime\n\ndt_1 = datetime(2025, 1, 14, 13, 45, 39, 132589)\ndt_2 = datetime(2025, 3, 16, 13, 45, 39, 132589)\n\nprint(f'Epoch between: {dt_1.timestamp()} - {dt_2.timestamp()}')\n\ntimestamp_filter = Timestamp(\"last_updated\").between(dt_1, dt_2)\n\nv.set_filter(timestamp_filter)\nresult_print(index.query(v))\n```\n\n    Epoch between: 1736880339.132589 - 1742147139.132589\n\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003cth\u003elast_updated\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ejohn\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e18\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ederrick\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e14\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.158808946609\u003c/td\u003e\u003ctd\u003etim\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e12\u003c/td\u003e\u003ctd\u003edermatologist\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1739644189\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n### Text Filters\n\nText filters are filters that are applied to text fields. These filters are applied to the entire text field. For example, if you have a text field that contains the text \"The quick brown fox jumps over the lazy dog\", a text filter of \"quick\" will match this text field.\n\n\n```python\nfrom redisvl.query.filter import Text\n\n# exact match filter -- document must contain the exact word doctor\ntext_filter = Text(\"job\") == \"doctor\"\n\nv.set_filter(text_filter)\nresult_print(index.query(v))\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003cth\u003elast_updated\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ederrick\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e14\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.266666650772\u003c/td\u003e\u003ctd\u003enancy\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e94\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1710696589\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n\n```python\n# negation -- document must not contain the exact word doctor\nnegate_text_filter = Text(\"job\") != \"doctor\"\n\nv.set_filter(negate_text_filter)\nresult_print(index.query(v))\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003cth\u003elast_updated\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ejohn\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e18\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.109129190445\u003c/td\u003e\u003ctd\u003etyler\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e100\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.158808946609\u003c/td\u003e\u003ctd\u003etim\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e12\u003c/td\u003e\u003ctd\u003edermatologist\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1739644189\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.217882037163\u003c/td\u003e\u003ctd\u003etaimur\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e15\u003c/td\u003e\u003ctd\u003eCEO\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.653301358223\u003c/td\u003e\u003ctd\u003ejoe\u003c/td\u003e\u003ctd\u003emedium\u003c/td\u003e\u003ctd\u003e35\u003c/td\u003e\u003ctd\u003edentist\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n\n```python\n# wildcard match filter\nwildcard_filter = Text(\"job\") % \"doct*\"\n\nv.set_filter(wildcard_filter)\nresult_print(index.query(v))\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003cth\u003elast_updated\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ederrick\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e14\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.266666650772\u003c/td\u003e\u003ctd\u003enancy\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e94\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1710696589\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n\n```python\n# fuzzy match filter\nfuzzy_match = Text(\"job\") % \"%%engine%%\"\n\nv.set_filter(fuzzy_match)\nresult_print(index.query(v))\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003cth\u003elast_updated\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ejohn\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e18\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.109129190445\u003c/td\u003e\u003ctd\u003etyler\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e100\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n\n```python\n# conditional -- match documents with job field containing engineer OR doctor\nconditional = Text(\"job\") % \"engineer|doctor\"\n\nv.set_filter(conditional)\nresult_print(index.query(v))\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003cth\u003elast_updated\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ejohn\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e18\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ederrick\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e14\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.109129190445\u003c/td\u003e\u003ctd\u003etyler\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e100\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.266666650772\u003c/td\u003e\u003ctd\u003enancy\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e94\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1710696589\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n\n```python\n# gracefully fallback to \"*\" filter if empty case\nempty_case = Text(\"job\") % \"\"\n\nv.set_filter(empty_case)\nresult_print(index.query(v))\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003cth\u003elast_updated\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ejohn\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e18\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ederrick\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e14\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.109129190445\u003c/td\u003e\u003ctd\u003etyler\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e100\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.158808946609\u003c/td\u003e\u003ctd\u003etim\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e12\u003c/td\u003e\u003ctd\u003edermatologist\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1739644189\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.217882037163\u003c/td\u003e\u003ctd\u003etaimur\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e15\u003c/td\u003e\u003ctd\u003eCEO\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.266666650772\u003c/td\u003e\u003ctd\u003enancy\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e94\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1710696589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.653301358223\u003c/td\u003e\u003ctd\u003ejoe\u003c/td\u003e\u003ctd\u003emedium\u003c/td\u003e\u003ctd\u003e35\u003c/td\u003e\u003ctd\u003edentist\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\nUse raw query strings as input. Below we use the `~` flag to indicate that the full text query is optional. We also choose the BM25 scorer and return document scores along with the result.\n\n\n```python\nv.set_filter(\"(~(@job:engineer))\")\nv.scorer(\"BM25\").with_scores()\n\nindex.query(v)\n```\n\n\n\n\n    [{'id': 'user_queries_docs:01JY4J5VC91SV4C91BM4D0FCV2',\n      'score': 0.9090908893868948,\n      'vector_distance': '0',\n      'user': 'john',\n      'credit_score': 'high',\n      'age': '18',\n      'job': 'engineer',\n      'office_location': '-122.4194,37.7749',\n      'last_updated': '1741627789'},\n     {'id': 'user_queries_docs:01JY4J5VC90DRSFJ0WKXXN49JT',\n      'score': 0.0,\n      'vector_distance': '0',\n      'user': 'derrick',\n      'credit_score': 'low',\n      'age': '14',\n      'job': 'doctor',\n      'office_location': '-122.4194,37.7749',\n      'last_updated': '1741627789'},\n     {'id': 'user_queries_docs:01JY4J5VC9QTPMCD60YP40Q6PW',\n      'score': 0.9090908893868948,\n      'vector_distance': '0.109129190445',\n      'user': 'tyler',\n      'credit_score': 'high',\n      'age': '100',\n      'job': 'engineer',\n      'office_location': '-122.0839,37.3861',\n      'last_updated': '1742232589'},\n     {'id': 'user_queries_docs:01JY4J5VC9FW7QQNJKDJ4Z7PRG',\n      'score': 0.0,\n      'vector_distance': '0.158808946609',\n      'user': 'tim',\n      'credit_score': 'high',\n      'age': '12',\n      'job': 'dermatologist',\n      'office_location': '-122.0839,37.3861',\n      'last_updated': '1739644189'},\n     {'id': 'user_queries_docs:01JY4J5VC940DJ9F47EJ6KN2MH',\n      'score': 0.0,\n      'vector_distance': '0.217882037163',\n      'user': 'taimur',\n      'credit_score': 'low',\n      'age': '15',\n      'job': 'CEO',\n      'office_location': '-122.0839,37.3861',\n      'last_updated': '1742232589'},\n     {'id': 'user_queries_docs:01JY4J5VC9D53KQD7ZTRP14KCE',\n      'score': 0.0,\n      'vector_distance': '0.266666650772',\n      'user': 'nancy',\n      'credit_score': 'high',\n      'age': '94',\n      'job': 'doctor',\n      'office_location': '-122.4194,37.7749',\n      'last_updated': '1710696589'},\n     {'id': 'user_queries_docs:01JY4J5VC9806MD90GBZNP0MNY',\n      'score': 0.0,\n      'vector_distance': '0.653301358223',\n      'user': 'joe',\n      'credit_score': 'medium',\n      'age': '35',\n      'job': 'dentist',\n      'office_location': '-122.0839,37.3861',\n      'last_updated': '1742232589'}]\n\n\n\n### Geographic Filters\n\nGeographic filters are filters that are applied to geographic fields. These filters are used to find results that are within a certain distance of a given point. The distance is specified in kilometers, miles, meters, or feet. A radius can also be specified to find results within a certain radius of a given point.\n\n\n```python\nfrom redisvl.query.filter import Geo, GeoRadius\n\n# within 10 km of San Francisco office\ngeo_filter = Geo(\"office_location\") == GeoRadius(-122.4194, 37.7749, 10, \"km\")\n\nv.set_filter(geo_filter)\nresult_print(index.query(v))\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003escore\u003c/th\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003cth\u003elast_updated\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.4545454446934474\u003c/td\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ejohn\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e18\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.4545454446934474\u003c/td\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ederrick\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e14\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.4545454446934474\u003c/td\u003e\u003ctd\u003e0.266666650772\u003c/td\u003e\u003ctd\u003enancy\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e94\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1710696589\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n\n```python\n# within 100 km Radius of San Francisco office\ngeo_filter = Geo(\"office_location\") == GeoRadius(-122.4194, 37.7749, 100, \"km\")\n\nv.set_filter(geo_filter)\nresult_print(index.query(v))\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003escore\u003c/th\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003cth\u003elast_updated\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.4545454446934474\u003c/td\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ejohn\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e18\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.4545454446934474\u003c/td\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ederrick\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e14\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1741627789\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.4545454446934474\u003c/td\u003e\u003ctd\u003e0.109129190445\u003c/td\u003e\u003ctd\u003etyler\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e100\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.4545454446934474\u003c/td\u003e\u003ctd\u003e0.158808946609\u003c/td\u003e\u003ctd\u003etim\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e12\u003c/td\u003e\u003ctd\u003edermatologist\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1739644189\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.4545454446934474\u003c/td\u003e\u003ctd\u003e0.217882037163\u003c/td\u003e\u003ctd\u003etaimur\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e15\u003c/td\u003e\u003ctd\u003eCEO\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.4545454446934474\u003c/td\u003e\u003ctd\u003e0.266666650772\u003c/td\u003e\u003ctd\u003enancy\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e94\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003ctd\u003e1710696589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.4545454446934474\u003c/td\u003e\u003ctd\u003e0.653301358223\u003c/td\u003e\u003ctd\u003ejoe\u003c/td\u003e\u003ctd\u003emedium\u003c/td\u003e\u003ctd\u003e35\u003c/td\u003e\u003ctd\u003edentist\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n\n```python\n# not within 10 km Radius of San Francisco office\ngeo_filter = Geo(\"office_location\") != GeoRadius(-122.4194, 37.7749, 10, \"km\")\n\nv.set_filter(geo_filter)\nresult_print(index.query(v))\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003escore\u003c/th\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003cth\u003elast_updated\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.0\u003c/td\u003e\u003ctd\u003e0.109129190445\u003c/td\u003e\u003ctd\u003etyler\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e100\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.0\u003c/td\u003e\u003ctd\u003e0.158808946609\u003c/td\u003e\u003ctd\u003etim\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e12\u003c/td\u003e\u003ctd\u003edermatologist\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1739644189\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.0\u003c/td\u003e\u003ctd\u003e0.217882037163\u003c/td\u003e\u003ctd\u003etaimur\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e15\u003c/td\u003e\u003ctd\u003eCEO\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.0\u003c/td\u003e\u003ctd\u003e0.653301358223\u003c/td\u003e\u003ctd\u003ejoe\u003c/td\u003e\u003ctd\u003emedium\u003c/td\u003e\u003ctd\u003e35\u003c/td\u003e\u003ctd\u003edentist\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003ctd\u003e1742232589\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n## Combining Filters\n\nIn this example, we will combine a numeric filter with a tag filter. We will search for users that are between the ages of 20 and 30 and have a job of \"engineer\".\n\n### Intersection (\"and\")\n\n\n```python\nt = Tag(\"credit_score\") == \"high\"\nlow = Num(\"age\") \u003e= 18\nhigh = Num(\"age\") \u003c= 100\nts = Timestamp(\"last_updated\") \u003e datetime(2025, 3, 16, 13, 45, 39, 132589)\n\ncombined = t \u0026 low \u0026 high \u0026 ts\n\nv = VectorQuery([0.1, 0.1, 0.5],\n                \"user_embedding\",\n                return_fields=[\"user\", \"credit_score\", \"age\", \"job\",  \"office_location\"],\n                filter_expression=combined)\n\n\nresult_print(index.query(v))\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.109129190445\u003c/td\u003e\u003ctd\u003etyler\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e100\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n### Union (\"or\")\n\nThe union of two queries is the set of all results that are returned by either of the two queries. The union of two queries is performed using the `|` operator.\n\n\n```python\nlow = Num(\"age\") \u003c 18\nhigh = Num(\"age\") \u003e 93\n\ncombined = low | high\n\nv.set_filter(combined)\nresult_print(index.query(v))\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ederrick\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e14\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.109129190445\u003c/td\u003e\u003ctd\u003etyler\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e100\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.158808946609\u003c/td\u003e\u003ctd\u003etim\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e12\u003c/td\u003e\u003ctd\u003edermatologist\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.217882037163\u003c/td\u003e\u003ctd\u003etaimur\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e15\u003c/td\u003e\u003ctd\u003eCEO\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.266666650772\u003c/td\u003e\u003ctd\u003enancy\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e94\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n### Dynamic Combination\n\nThere are often situations where you may or may not want to use a filter in a\ngiven query. As shown above, filters will except the ``None`` type and revert\nto a wildcard filter essentially returning all results.\n\nThe same goes for filter combinations which enables rapid reuse of filters in\nrequests with different parameters as shown below. This removes the need for\na number of \"if-then\" conditionals to test for the empty case.\n\n\n\n\n```python\ndef make_filter(age=None, credit=None, job=None):\n    flexible_filter = (\n        (Num(\"age\") \u003e age) \u0026\n        (Tag(\"credit_score\") == credit) \u0026\n        (Text(\"job\") % job)\n    )\n    return flexible_filter\n\n```\n\n\n```python\n# all parameters\ncombined = make_filter(age=18, credit=\"high\", job=\"engineer\")\nv.set_filter(combined)\nresult_print(index.query(v))\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.109129190445\u003c/td\u003e\u003ctd\u003etyler\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e100\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n\n```python\n# just age and credit_score\ncombined = make_filter(age=18, credit=\"high\")\nv.set_filter(combined)\nresult_print(index.query(v))\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.109129190445\u003c/td\u003e\u003ctd\u003etyler\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e100\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.266666650772\u003c/td\u003e\u003ctd\u003enancy\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e94\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n\n```python\n# just age\ncombined = make_filter(age=18)\nv.set_filter(combined)\nresult_print(index.query(v))\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.109129190445\u003c/td\u003e\u003ctd\u003etyler\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e100\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.266666650772\u003c/td\u003e\u003ctd\u003enancy\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e94\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.653301358223\u003c/td\u003e\u003ctd\u003ejoe\u003c/td\u003e\u003ctd\u003emedium\u003c/td\u003e\u003ctd\u003e35\u003c/td\u003e\u003ctd\u003edentist\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n\n```python\n# no filters\ncombined = make_filter()\nv.set_filter(combined)\nresult_print(index.query(v))\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ejohn\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e18\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ederrick\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e14\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.109129190445\u003c/td\u003e\u003ctd\u003etyler\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e100\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.158808946609\u003c/td\u003e\u003ctd\u003etim\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e12\u003c/td\u003e\u003ctd\u003edermatologist\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.217882037163\u003c/td\u003e\u003ctd\u003etaimur\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e15\u003c/td\u003e\u003ctd\u003eCEO\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.266666650772\u003c/td\u003e\u003ctd\u003enancy\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e94\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.653301358223\u003c/td\u003e\u003ctd\u003ejoe\u003c/td\u003e\u003ctd\u003emedium\u003c/td\u003e\u003ctd\u003e35\u003c/td\u003e\u003ctd\u003edentist\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n## Non-vector Queries\n\nIn some cases, you may not want to run a vector query, but just use a ``FilterExpression`` similar to a SQL query. The ``FilterQuery`` class enable this functionality. It is similar to the ``VectorQuery`` class but solely takes a ``FilterExpression``.\n\n\n```python\nfrom redisvl.query import FilterQuery\n\nhas_low_credit = Tag(\"credit_score\") == \"low\"\n\nfilter_query = FilterQuery(\n    return_fields=[\"user\", \"credit_score\", \"age\", \"job\", \"location\"],\n    filter_expression=has_low_credit\n)\n\nresults = index.query(filter_query)\n\nresult_print(results)\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ederrick\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e14\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003etaimur\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e15\u003c/td\u003e\u003ctd\u003eCEO\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n## Count Queries\n\nIn some cases, you may need to use a ``FilterExpression`` to execute a ``CountQuery`` that simply returns the count of the number of entities in the pertaining set. It is similar to the ``FilterQuery`` class but does not return the values of the underlying data.\n\n\n```python\nfrom redisvl.query import CountQuery\n\nhas_low_credit = Tag(\"credit_score\") == \"low\"\n\nfilter_query = CountQuery(filter_expression=has_low_credit)\n\ncount = index.query(filter_query)\n\nprint(f\"{count} records match the filter expression {str(has_low_credit)} for the given index.\")\n```\n\n    2 records match the filter expression @credit_score:{low} for the given index.\n\n\n## Range Queries\n\nRange Queries are a useful method to perform a vector search where only results within a vector ``distance_threshold`` are returned. This enables the user to find all records within their dataset that are similar to a query vector where \"similar\" is defined by a quantitative value.\n\n\n```python\nfrom redisvl.query import RangeQuery\n\nrange_query = RangeQuery(\n    vector=[0.1, 0.1, 0.5],\n    vector_field_name=\"user_embedding\",\n    return_fields=[\"user\", \"credit_score\", \"age\", \"job\", \"location\"],\n    distance_threshold=0.2\n)\n\n# same as the vector query or filter query\nresults = index.query(range_query)\n\nresult_print(results)\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ejohn\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e18\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ederrick\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e14\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.109129190445\u003c/td\u003e\u003ctd\u003etyler\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e100\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.158808946609\u003c/td\u003e\u003ctd\u003etim\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e12\u003c/td\u003e\u003ctd\u003edermatologist\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\nWe can also change the distance threshold of the query object between uses if we like. Here we will set ``distance_threshold==0.1``. This means that the query object will return all matches that are within 0.1 of the query object. This is a small distance, so we expect to get fewer matches than before.\n\n\n```python\nrange_query.set_distance_threshold(0.1)\n\nresult_print(index.query(range_query))\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ejohn\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e18\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ederrick\u003c/td\u003e\u003ctd\u003elow\u003c/td\u003e\u003ctd\u003e14\u003c/td\u003e\u003ctd\u003edoctor\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\nRange queries can also be used with filters like any other query type. The following limits the results to only include records with a ``job`` of ``engineer`` while also being within the vector range (aka distance).\n\n\n```python\nis_engineer = Text(\"job\") == \"engineer\"\n\nrange_query.set_filter(is_engineer)\n\nresult_print(index.query(range_query))\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003ejohn\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003e18\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n## Advanced Query Modifiers\n\nSee all modifier options available on the query API docs: https://redis.io/docs/latest/develop/ai/redisvl/api/query\n\n\n```python\n# Sort by a different field and change dialect\nv = VectorQuery(\n    vector=[0.1, 0.1, 0.5],\n    vector_field_name=\"user_embedding\",\n    return_fields=[\"user\", \"credit_score\", \"age\", \"job\",  \"office_location\"],\n    num_results=5,\n    filter_expression=is_engineer\n).sort_by(\"age\", asc=False).dialect(3)\n\nresult = index.query(v)\nresult_print(result)\n```\n\n\n\u003ctable\u003e\u003ctr\u003e\u003cth\u003evector_distance\u003c/th\u003e\u003cth\u003eage\u003c/th\u003e\u003cth\u003euser\u003c/th\u003e\u003cth\u003ecredit_score\u003c/th\u003e\u003cth\u003ejob\u003c/th\u003e\u003cth\u003eoffice_location\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0.109129190445\u003c/td\u003e\u003ctd\u003e100\u003c/td\u003e\u003ctd\u003etyler\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.0839,37.3861\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003e18\u003c/td\u003e\u003ctd\u003ejohn\u003c/td\u003e\u003ctd\u003ehigh\u003c/td\u003e\u003ctd\u003eengineer\u003c/td\u003e\u003ctd\u003e-122.4194,37.7749\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n\n### Raw Redis Query String\n\nSometimes it's helpful to convert these classes into their raw Redis query strings.\n\n\n```python\n# check out the complex query from above\nstr(v)\n```\n\n\n\n\n    '@job:(\"engineer\")=\u003e[KNN 5 @user_embedding $vector AS vector_distance] RETURN 6 user credit_score age job office_location vector_distance SORTBY age DESC DIALECT 3 LIMIT 0 5'\n\n\n\n\n```python\nt = Tag(\"credit_score\") == \"high\"\n\nstr(t)\n```\n\n\n\n\n    '@credit_score:{high}'\n\n\n\n\n```python\nt = Tag(\"credit_score\") == \"high\"\nlow = Num(\"age\") \u003e= 18\nhigh = Num(\"age\") \u003c= 100\n\ncombined = t \u0026 low \u0026 high\n\nstr(combined)\n```\n\n\n\n\n    '((@credit_score:{high} @age:[18 +inf]) @age:[-inf 100])'\n\n\n\nThe RedisVL `SearchIndex` class exposes a `search()` method which is a simple wrapper around the `FT.SEARCH` API.\nProvide any valid Redis query string.\n\n\n```python\nresults = index.search(str(t))\nfor r in results.docs:\n    print(r.__dict__)\n```\n\n    {'id': 'user_queries_docs:01JY4J5VC91SV4C91BM4D0FCV2', 'payload': None, 'user': 'john', 'age': '18', 'job': 'engineer', 'credit_score': 'high', 'office_location': '-122.4194,37.7749', 'user_embedding': '==\\x00\\x00\\x00?', 'last_updated': '1741627789'}\n    {'id': 'user_queries_docs:01JY4J5VC9D53KQD7ZTRP14KCE', 'payload': None, 'user': 'nancy', 'age': '94', 'job': 'doctor', 'credit_score': 'high', 'office_location': '-122.4194,37.7749', 'user_embedding': '333?=\\x00\\x00\\x00?', 'last_updated': '1710696589'}\n    {'id': 'user_queries_docs:01JY4J5VC9QTPMCD60YP40Q6PW', 'payload': None, 'user': 'tyler', 'age': '100', 'job': 'engineer', 'credit_score': 'high', 'office_location': '-122.0839,37.3861', 'user_embedding': '=\u003e\\x00\\x00\\x00?', 'last_updated': '1742232589'}\n    {'id': 'user_queries_docs:01JY4J5VC9FW7QQNJKDJ4Z7PRG', 'payload': None, 'user': 'tim', 'age': '12', 'job': 'dermatologist', 'credit_score': 'high', 'office_location': '-122.0839,37.3861', 'user_embedding': '\u003e\u003e\\x00\\x00\\x00?', 'last_updated': '1739644189'}\n\n\n\n```python\n# Cleanup\nindex.delete()\n```\n",
  "tags": [],
  "last_updated": "2026-04-21T14:39:33+02:00"
}
