{
  "schema_version": 2,
  "id": "develop/ai/search-and-query/query/combined",
  "title": "Combined queries",
  "url": "https://redis.io/docs/latest/develop/ai/search-and-query/query/combined/",
  "summary": "Combine query expressions",
  "aliases": [
    "/develop/interact/search-and-query/query/combined"
  ],
  "tags": [
    "docs",
    "develop",
    "stack",
    "oss",
    "rs",
    "rc",
    "oss",
    "kubernetes",
    "clients"
  ],
  "last_updated": "2026-09-11T15:33:04+01:00",
  "page_type": "content",
  "content_hash": "1f1fbd4cde09d6decf4eae44ab0e63d02ed25d5e39be739f0f19386fae39330f",
  "sections": [
    {
      "id": "and",
      "title": "AND",
      "role": "content",
      "text": "The binary operator ` ` (space) is used to intersect the results of two or more expressions.\n\n[code example]\n\nIf you want to perform an intersection based on multiple values within a specific text field, then you should use the following simplified notion:\n\n[code example]\n\nThe following example shows you a query that finds bicycles in new condition and in a price range from 500 USD to 1000 USD:\n\nAND operator: Combine multiple query expressions using space to find documents matching all criteria when you need to narrow results with multiple filters\n\n**Difficulty:** Beginner\n\n**Available in:** Redis CLI, JavaScript (Node.js), Python\n\n##### Redis CLI\n\n[code example]\n\n##### JavaScript (Node.js)\n\n[code example]\n\n##### Python\n\n[code example]\n\n\n\nYou might also be interested in bicycles for kids. The query below shows you how to combine a full-text search with the criteria from the previous query:\n\nAND with full-text: Combine full-text search with structured queries using AND when you need to find documents with specific text and matching field values\n\n**Difficulty:** Beginner\n\n**Available in:** Redis CLI, JavaScript (Node.js), Python\n\n##### Redis CLI\n\n[code example]\n\n##### JavaScript (Node.js)\n\n[code example]\n\n##### Python\n\n[code example]"
    },
    {
      "id": "or",
      "title": "OR",
      "role": "content",
      "text": "You can use the binary operator `|` (vertical bar) to perform a union.\n\n[code example]\n\n> [!NOTE]\n> The logical `AND` takes precedence over `OR` when using dialect version two. The expression `expr1 expr2 | expr3 expr4` means `(expr1 expr2) | (expr3 expr4)`. Version one of the query dialect behaves differently. Using parentheses in query strings is advised to ensure the order is clear.\n>  \n\n\nIf you want to perform the union based on multiple values within a single tag or text field, then you should use the following simplified notion:\n\n[code example]\n\n[code example]\n\nThe following query shows you how to find used bicycles that contain either the word 'kids' or 'small':\n\nOR operator: Combine multiple expressions using the pipe operator to find documents matching any criteria when you need to broaden results with alternatives\n\n**Difficulty:** Intermediate\n\n**Available in:** Redis CLI, JavaScript (Node.js), Python\n\n##### Redis CLI\n\n[code example]\n\n##### JavaScript (Node.js)\n\n[code example]\n\n##### Python\n\n[code example]\n\n\n\nThe previous query searches across all text fields. The following example shows you how to limit the search to the description field:\n\nOR within a field: Use OR to search for multiple values within a single field when you need to match any of several options in one field\n\n**Difficulty:** Intermediate\n\n**Available in:** Redis CLI, JavaScript (Node.js), Python\n\n##### Redis CLI\n\n[code example]\n\n##### JavaScript (Node.js)\n\n[code example]\n\n##### Python\n\n[code example]\n\n\n\nIf you want to extend the search to new bicycles, then the below example shows you how to do that:\n\nOR across multiple fields: Combine OR operators across different fields when you need to match alternatives in multiple field criteria\n\n**Difficulty:** Intermediate\n\n**Available in:** Redis CLI, JavaScript (Node.js), Python\n\n##### Redis CLI\n\n[code example]\n\n##### JavaScript (Node.js)\n\n[code example]\n\n##### Python\n\n[code example]"
    },
    {
      "id": "not",
      "title": "NOT",
      "role": "content",
      "text": "A minus (`-`) in front of a query expression negates the expression.\n\n[code example]\n\nIf you want to exclude new bicycles from the search within the previous price range, you can use this query:\n\nNOT operator: Negate query expressions using minus to exclude documents matching criteria when you need to filter out unwanted results\n\n**Difficulty:** Intermediate\n\n**Available in:** Redis CLI, JavaScript (Node.js), Python\n\n##### Redis CLI\n\n[code example]\n\n##### JavaScript (Node.js)\n\n[code example]\n\n##### Python\n\n[code example]"
    },
    {
      "id": "numeric-filter",
      "title": "Numeric filter",
      "role": "content",
      "text": "The [FT.SEARCH](https://redis.io/docs/latest/commands/ft.search) command allows you to combine any query expression with a numeric filter.\n\n[code example]\n\nPlease see the [range query article](https://redis.io/docs/latest/develop/ai/search-and-query/query/range) to learn more about numeric range queries and such filters."
    },
    {
      "id": "pre-filter-for-a-knn--vector-query",
      "title": "Pre-filter for a KNN  vector query",
      "role": "content",
      "text": "You can use a simple or more complex query expression with logical operators as a pre-filter in a KNN vector query. \n\n[code example]\n\nHere is an example:\n\nVector pre-filtering: Use structured queries as pre-filters before KNN vector search when you need to find similar items within a specific subset of data\n\n**Difficulty:** Advanced\n\n**Available in:** Redis CLI, JavaScript (Node.js), Python\n\n##### Redis CLI\n\n[code example]\n\n##### JavaScript (Node.js)\n\n[code example]\n\n##### Python\n\n[code example]\n\n\n\nThe [vector search article](https://redis.io/docs/latest/develop/ai/search-and-query/query/vector-search) provides further details about vector queries in general."
    }
  ],
  "examples": [
    {
      "id": "and-ex0",
      "language": "plaintext",
      "code": "FT.SEARCH index \"(expr1) (expr2)\"",
      "section_id": "and"
    },
    {
      "id": "and-ex1",
      "language": "plaintext",
      "code": "FT.SEARCH index \"@text_field:( value1 value2 ... )\"",
      "section_id": "and"
    },
    {
      "id": "and-ex2",
      "language": "plaintext",
      "code": "FT.SEARCH idx:bicycle \"@price:[500 1000] @condition:{new}\"",
      "section_id": "and"
    },
    {
      "id": "and-ex3",
      "language": "javascript",
      "code": "const res1 = await client.ft.search('idx:bicycle', '@price:[500 1000] @condition:{new}');\nconsole.log(res1.total); // >>> 1\nconsole.log(res1); // >>>\n//{\n//  total: 1,\n//  documents: [ { id: 'bicycle:5', value: [Object: null prototype] } ]\n//}",
      "section_id": "and"
    },
    {
      "id": "and-ex4",
      "language": "python",
      "code": "q = Query(\"@price:[500 1000] @condition:{new}\")\nres = index.search(q)\nprint(res.total) # >>> 1",
      "section_id": "and"
    },
    {
      "id": "and-ex5",
      "language": "plaintext",
      "code": "FT.SEARCH idx:bicycle \"kids (@price:[500 1000] @condition:{used})\"",
      "section_id": "and"
    },
    {
      "id": "and-ex6",
      "language": "javascript",
      "code": "const res2 = await client.ft.search('idx:bicycle', 'kids @price:[500 1000] @condition:{used}');\nconsole.log(res2.total); // >>> 1\nconsole.log(res2); // >>>\n// {\n//   total: 1,\n//   documents: [ { id: 'bicycle:2', value: [Object: null prototype] } ]\n// }",
      "section_id": "and"
    },
    {
      "id": "and-ex7",
      "language": "python",
      "code": "q = Query(\"kids @price:[500 1000] @condition:{used}\")\nres = index.search(q)\nprint(res.total) # >>> 1",
      "section_id": "and"
    },
    {
      "id": "or-ex0",
      "language": "plaintext",
      "code": "FT.SEARCH index \"(expr1) | (expr2)\"",
      "section_id": "or"
    },
    {
      "id": "or-ex1",
      "language": "plaintext",
      "code": "FT.SEARCH index \"@text_field:( value1 | value2 | ... )\"",
      "section_id": "or"
    },
    {
      "id": "or-ex2",
      "language": "plaintext",
      "code": "FT.SEARCH index \"@tag_field:{ value1 | value2 | ... }\"",
      "section_id": "or"
    },
    {
      "id": "or-ex3",
      "language": "plaintext",
      "code": "FT.SEARCH idx:bicycle \"(kids | small) @condition:{used}\"",
      "section_id": "or"
    },
    {
      "id": "or-ex4",
      "language": "javascript",
      "code": "const res3 = await client.ft.search('idx:bicycle', '(kids | small) @condition:{used}');\nconsole.log(res3.total); // >>> 2\nconsole.log(res3); // >>>\n//{\n//  total: 2,\n//  documents: [\n//    { id: 'bicycle:2', value: [Object: null prototype] },\n//    { id: 'bicycle:1', value: [Object: null prototype] }\n//  ]\n//}",
      "section_id": "or"
    },
    {
      "id": "or-ex5",
      "language": "python",
      "code": "q = Query(\"(kids | small) @condition:{used}\")\nres = index.search(q)\nprint(res.total) # >>> 2",
      "section_id": "or"
    },
    {
      "id": "or-ex6",
      "language": "plaintext",
      "code": "FT.SEARCH idx:bicycle \"@description:(kids | small) @condition:{used}\"",
      "section_id": "or"
    },
    {
      "id": "or-ex7",
      "language": "javascript",
      "code": "const res4 = await client.ft.search('idx:bicycle', '@description:(kids | small) @condition:{used}');\nconsole.log(res4.total); // >>> 2\nconsole.log(res4); // >>>\n//{\n//  total: 2,\n//  documents: [\n//    { id: 'bicycle:2', value: [Object: null prototype] },\n//    { id: 'bicycle:1', value: [Object: null prototype] }\n//  ]\n//}",
      "section_id": "or"
    },
    {
      "id": "or-ex8",
      "language": "python",
      "code": "q = Query(\"@description:(kids | small) @condition:{used}\")\nres = index.search(q)\nprint(res.total) # >>> 0",
      "section_id": "or"
    },
    {
      "id": "or-ex9",
      "language": "plaintext",
      "code": "FT.SEARCH idx:bicycle \"@description:(kids | small) @condition:{new | used}\"",
      "section_id": "or"
    },
    {
      "id": "or-ex10",
      "language": "javascript",
      "code": "const res5 = await client.ft.search('idx:bicycle', '@description:(kids | small) @condition:{new | used}');\nconsole.log(res5.total); // >>> 3\nconsole.log(res5); // >>>\n//{\n//  total: 3,\n//  documents: [\n//    { id: 'bicycle:1', value: [Object: null prototype] },\n//    { id: 'bicycle:0', value: [Object: null prototype] },\n//    { id: 'bicycle:2', value: [Object: null prototype] }\n//  ]\n//}",
      "section_id": "or"
    },
    {
      "id": "or-ex11",
      "language": "python",
      "code": "q = Query(\"@description:(kids | small) @condition:{new | used}\")\nres = index.search(q)\nprint(res.total) # >>> 0",
      "section_id": "or"
    },
    {
      "id": "not-ex0",
      "language": "plaintext",
      "code": "FT.SEARCH index \"-(expr)\"",
      "section_id": "not"
    },
    {
      "id": "not-ex1",
      "language": "plaintext",
      "code": "FT.SEARCH idx:bicycle \"@price:[500 1000] -@condition:{new}\"",
      "section_id": "not"
    },
    {
      "id": "not-ex2",
      "language": "javascript",
      "code": "const res6 = await client.ft.search('idx:bicycle', '@price:[500 1000] -@condition:{new}');\nconsole.log(res6.total); // >>> 2\nconsole.log(res6); // >>>\n//{\n//  total: 2,\n//  documents: [\n//    { id: 'bicycle:2', value: [Object: null prototype] },\n//    { id: 'bicycle:9', value: [Object: null prototype] }\n//  ]\n//}",
      "section_id": "not"
    },
    {
      "id": "not-ex3",
      "language": "python",
      "code": "q = Query(\"@price:[500 1000] -@condition:{new}\")\nres = index.search(q)\nprint(res.total) # >>> 2",
      "section_id": "not"
    },
    {
      "id": "numeric-filter-ex0",
      "language": "plaintext",
      "code": "FT.SEARCH index \"expr\" FILTER numeric_field start end",
      "section_id": "numeric-filter"
    },
    {
      "id": "pre-filter-for-a-knn--vector-query-ex0",
      "language": "plaintext",
      "code": "FT.SEARCH index \"(filter_expr)=>[KNN num_neighbours @field $vector]\" PARAMS 2 vector \"binary_data\" DIALECT 2",
      "section_id": "pre-filter-for-a-knn--vector-query"
    },
    {
      "id": "pre-filter-for-a-knn--vector-query-ex1",
      "language": "plaintext",
      "code": "FT.SEARCH idx:bikes_vss \"(@price:[500 1000] @condition:{new})=>[KNN 3 @vector $query_vector]\" PARAMS 2 \"query_vector\" \"Z\\xf8\\x15:\\xf23\\xa1\\xbfZ\\x1dI>\\r\\xca9...\" DIALECT 2",
      "section_id": "pre-filter-for-a-knn--vector-query"
    },
    {
      "id": "pre-filter-for-a-knn--vector-query-ex2",
      "language": "javascript",
      "code": "const res7 = await client.ft.search('idx:bicycle', \n  '(@price:[500 1000] -@condition:{new})=>[KNN 3 @vector $query_vector]', {\n    PARAMS: { query_vector: vector_query },\n    DIALECT: 2\n  }\n);\nconsole.log(res7.total); // >>> 2\nconsole.log(res7); // >>>\n//{\n//  total: 2,\n//  documents: [\n//    { id: 'bicycle:2', value: [Object: null prototype] },\n//    { id: 'bicycle:9', value: [Object: null prototype] }\n//  ]\n//}",
      "section_id": "pre-filter-for-a-knn--vector-query"
    },
    {
      "id": "pre-filter-for-a-knn--vector-query-ex3",
      "language": "python",
      "code": "q = Query(\"(@price:[500 1000] -@condition:{new})=>[KNN 3 @vector $query_vector]\").dialect(2)\n# put query string here\nres = index.search(q,{ 'query_vector': query_vector })\nprint(res.total) # >>> 2",
      "section_id": "pre-filter-for-a-knn--vector-query"
    }
  ]
}
