{
  "id": "hybrid_queries",
  "title": "Querying with RedisVL",
  "url": "https://redis.io/docs/latest/develop/ai/redisvl/0.9.1/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\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-08T12:21:52-07:00"
}

