|
| 1 | +--- |
| 2 | +categories: |
| 3 | +- docs |
| 4 | +- develop |
| 5 | +- stack |
| 6 | +- oss |
| 7 | +- rs |
| 8 | +- rc |
| 9 | +- oss |
| 10 | +- kubernetes |
| 11 | +- clients |
| 12 | +description: Query for data based on vector embeddings |
| 13 | +linkTitle: Vector search examples |
| 14 | +title: Vector search examples |
| 15 | +weight: 2 |
| 16 | +--- |
| 17 | + |
| 18 | +This article gives you a good overview of how to perform vector search queries with Redis Stack. See the [Redis as a vector database quick start guide]({{< relref "/develop/ai/vector-database" >}}) for more information about Redis as a vector database. You can also find more detailed information about all the parameters in the [vector reference documentation]({{< relref "/develop/ai/vector-fields" >}}). |
| 19 | + |
| 20 | +A vector search query on a vector field allows you to find all vectors in a vector space that are close to a given vector. You can query for the k-nearest neighbors or vectors within a given radius. |
| 21 | + |
| 22 | +The examples in this article use a schema with the following fields: |
| 23 | + |
| 24 | +| JSON field | Field alias | Field type | Description | |
| 25 | +| ------------------------ | ----------- | ----------- | ----------- | |
| 26 | +| `$.description` | `description` | `TEXT` | The description of a bicycle as unstructured text | |
| 27 | +| `$.description_embeddings` | `vector` | `VECTOR` | The vector that a machine learning model derived from the description text | |
| 28 | + |
| 29 | +## K-neareast neighbours (KNN) |
| 30 | + |
| 31 | +The Redis command [FT.SEARCH]({{< relref "commands/ft.search" >}}) takes the index name, the query string, and additional query parameters as arguments. You need to pass the number of nearest neighbors, the vector field name, and the vector's binary representation in the following way: |
| 32 | + |
| 33 | +``` |
| 34 | +FT.SEARCH index "(*)=>[KNN num_neighbours @field $vector]" PARAMS 2 vector "binary_data" DIALECT 2 |
| 35 | +``` |
| 36 | + |
| 37 | +Here is a more detailed explanation of this query: |
| 38 | + |
| 39 | +1. **Pre-filter**: The first expression within the round brackets is a filter. It allows you to decide which vectors should be taken into account before the vector search is performed. The expression `(*)` means that all vectors are considered. |
| 40 | +2. **Next step**: The `=>` arrow indicates that the pre-filtering happens before the vector search. |
| 41 | +3. **KNN query**: The expression `[KNN num_neighbours @field $vector]` is a parameterized query expression. A parameter name is indicated by the `$` prefix within the query string. |
| 42 | +4. **Vector binary data**: You need to use the `PARAMS` argument to substitute `$vector` with the binary representation of the vector. The value `2` indicates that `PARAMS` is followed by two arguments, the parameter name `vector` and the parameter value. |
| 43 | +5. **Dialect**: The vector search feature has been available since version two of the query dialect. |
| 44 | + |
| 45 | +You can read more about the `PARAMS` argument in the [FT.SEARCH]({{< relref "commands/ft.search" >}}) command reference. |
| 46 | + |
| 47 | +The following example shows you how to query for three bikes based on their description embeddings, and by using the field alias `vector`. The result is returned in ascending order based on the distance. You can see that the query only returns the fields `__vector_score` and `description`. The field `__vector_score` is present by default. Because you can have multiple vector fields in your schema, the vector score field name depends on the name of the vector field. If you change the field name `@vector` to `@foo`, the score field name changes to `__foo_score`. |
| 48 | + |
| 49 | +{{< clients-example query_vector vector1 >}} |
| 50 | +FT.SEARCH idx:bikes_vss "(*)=>[KNN 3 @vector $query_vector]" PARAMS 2 "query_vector" "Z\xf8\x15:\xf23\xa1\xbfZ\x1dI>\r\xca9..." SORTBY "__vector_score" ASC RETURN 2 "__vector_score" "description" DIALECT 2 |
| 51 | +{{< /clients-example >}} |
| 52 | + |
| 53 | +<!-- Python query> |
| 54 | +query = ( |
| 55 | + Query('(*)=>[KNN 3 @vector $query_vector]') |
| 56 | + .sort_by('__vector_score') |
| 57 | + .return_fields('__vector_score', 'description') |
| 58 | + .dialect(2) |
| 59 | +) |
| 60 | +</!--> |
| 61 | + |
| 62 | +{{% alert title="Note" color="warning" %}} |
| 63 | +The binary value of the query vector is significantly shortened in the CLI example above. |
| 64 | +{{% /alert %}} |
| 65 | + |
| 66 | + |
| 67 | +## Radius |
| 68 | + |
| 69 | +Instead of the number of nearest neighbors, you need to pass the radius along with the index name, the vector field name, and the vector's binary value: |
| 70 | + |
| 71 | +``` |
| 72 | +FT.SEARCH index "@field:[VECTOR_RANGE radius $vector]" PARAMS 2 vector "binary_data" DIALECT 2 |
| 73 | +``` |
| 74 | + |
| 75 | +If you want to sort by distance, then you must yield the distance via the range query parameter `$YIELD_DISTANCE_AS`: |
| 76 | + |
| 77 | +``` |
| 78 | +FT.SEARCH index "@field:[VECTOR_RANGE radius $vector]=>{$YIELD_DISTANCE_AS: dist_field}" PARAMS 2 vector "binary_data" SORTBY dist_field DIALECT 2 |
| 79 | +``` |
| 80 | + |
| 81 | +Here is a more detailed explanation of this query: |
| 82 | + |
| 83 | +1. **Range query**: the syntax of a radius query is very similar to the regular range query, except for the keyword `VECTOR_RANGE`. You can also combine a vector radius query with other queries in the same way as regular range queries. See [combined queries article]({{< relref "/develop/interact/search-and-query/query/combined" >}}) for more details. |
| 84 | +2. **Additional step**: the `=>` arrow means that the range query is followed by evaluating additional parameters. |
| 85 | +3. **Range query parameters**: parameters such as `$YIELD_DISTANCE_AS` can be found in the [vectors reference documentation]({{< relref "/develop/ai/vector-fields" >}}). |
| 86 | +4. **Vector binary data**: you need to use `PARAMS` to pass the binary representation of the vector. |
| 87 | +5. **Dialect**: vector search has been available since version two of the query dialect. |
| 88 | + |
| 89 | + |
| 90 | +{{% alert title="Note" color="warning" %}} |
| 91 | +By default, [`FT.SEARCH`]({{< relref "commands/ft.search/" >}}) returns only the first ten results. The [range query article]({{< relref "/develop/interact/search-and-query/query/range" >}}) explains to you how to scroll through the result set. |
| 92 | +{{% /alert %}} |
| 93 | + |
| 94 | +The example below shows a radius query that returns the description and the distance within a radius of `0.5`. The result is sorted by the distance. |
| 95 | + |
| 96 | +{{< clients-example query_vector vector2 >}} |
| 97 | +FT.SEARCH idx:bikes_vss "@vector:[VECTOR_RANGE 0.5 $query_vector]=>{$YIELD_DISTANCE_AS: vector_dist}" PARAMS 2 "query_vector" "Z\xf8\x15:\xf23\xa1\xbfZ\x1dI>\r\xca9..." SORTBY vector_dist ASC RETURN 2 vector_dist description DIALECT 2 |
| 98 | +{{< /clients-example >}} |
| 99 | + |
| 100 | +<!-- Python query> |
| 101 | +query = ( |
| 102 | + Query('@vector:[VECTOR_RANGE 0.5 $query_vector]=>{$YIELD_DISTANCE_AS: vector_dist}') |
| 103 | + .sort_by('vector_dist') |
| 104 | + .return_fields('vector_dist', 'description') |
| 105 | + .dialect(2) |
| 106 | +) |
| 107 | +</!--> |
0 commit comments