Skip to content

Commit 98e267c

Browse files
Merge pull request #1965 from redis/DOC-5556-lettuce-query-examples
DOC-5556 lettuce index/query example
2 parents 518725f + 29c8cec commit 98e267c

File tree

12 files changed

+853
-10
lines changed

12 files changed

+853
-10
lines changed

build/local_examples.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,24 @@ def get_client_name_from_language(language: str) -> str:
5151
return LANGUAGE_TO_CLIENT.get(language, language.title())
5252

5353

54+
def get_client_name_from_language_and_path(language: str, path: str) -> str:
55+
"""Get client name from language with path-based overrides.
56+
57+
For Java (.java) files, override based on path substrings:
58+
- If 'lettuce-async' in path -> Java-Async
59+
- If 'lettuce-reactive' in path -> Java-Reactive
60+
61+
Substring checks are case-sensitive and can appear anywhere in the path.
62+
"""
63+
if language == 'java':
64+
if 'lettuce-async' in path:
65+
return 'Java-Async'
66+
if 'lettuce-reactive' in path:
67+
return 'Java-Reactive'
68+
# Default behavior for all languages (and Java fallback)
69+
return get_client_name_from_language(language)
70+
71+
5472
def get_example_id_from_file(path: str) -> str:
5573
"""Extract example ID from the first line of a file."""
5674
try:
@@ -136,8 +154,8 @@ def process_local_examples(local_examples_dir: str = 'local_examples',
136154
# Process with Example class
137155
example = Example(language, target_file)
138156

139-
# Get client name
140-
client_name = get_client_name_from_language(language)
157+
# Get client name (with Java path-based overrides)
158+
client_name = get_client_name_from_language_and_path(language, source_file)
141159

142160
# Create metadata
143161
example_metadata = {
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
---
2+
categories:
3+
- docs
4+
- develop
5+
- stack
6+
- oss
7+
- rs
8+
- rc
9+
- oss
10+
- kubernetes
11+
- clients
12+
description: Learn how to use the Redis query engine with JSON and hash documents.
13+
linkTitle: Index and query documents
14+
title: Index and query documents
15+
weight: 2
16+
---
17+
18+
This example shows how to create a
19+
[search index]({{< relref "/develop/ai/search-and-query/indexing" >}})
20+
for [JSON]({{< relref "/develop/data-types/json" >}}) documents and
21+
run queries against the index. It then goes on to show the slight differences
22+
in the equivalent code for [hash]({{< relref "/develop/data-types/hashes" >}})
23+
documents.
24+
25+
## Initialize
26+
27+
Make sure that you have [Redis Open Source]({{< relref "/operate/oss_and_stack/" >}})
28+
or another Redis server available. Also install the
29+
[Lettuce]({{< relref "/develop/clients/lettuce" >}}) client library if you
30+
haven't already done so.
31+
32+
Add the following dependencies. All of them are applicable to both JSON and hash,
33+
except for the `JsonParser`, `JsonPath`, and `JsonObject` classes.
34+
35+
{{< clients-example lettuce_home_json import >}}
36+
{{< /clients-example >}}
37+
38+
## Create data
39+
40+
Create some test data to add to the database:
41+
42+
{{< clients-example lettuce_home_json create_data >}}
43+
{{< /clients-example >}}
44+
45+
## Add the index
46+
47+
Connect to your Redis database. The code below shows the most
48+
basic connection but see
49+
[Connect to the server]({{< relref "/develop/clients/lettuce/connect" >}})
50+
to learn more about the available connection options.
51+
52+
{{< clients-example lettuce_home_json connect >}}
53+
{{< /clients-example >}}
54+
55+
Create an index. In this example, only JSON documents with the key prefix `user:` are indexed. For more information, see [Query syntax]({{< relref "/develop/ai/search-and-query/query/" >}}).
56+
57+
{{< clients-example lettuce_home_json make_index >}}
58+
{{< /clients-example >}}
59+
60+
## Add the data
61+
62+
Add the three sets of user data to the database as
63+
[JSON]({{< relref "/develop/data-types/json" >}}) objects.
64+
If you use keys with the `user:` prefix then Redis will index the
65+
objects automatically as you add them:
66+
67+
{{< clients-example lettuce_home_json add_data >}}
68+
{{< /clients-example >}}
69+
70+
## Query the data
71+
72+
You can now use the index to search the JSON objects. The
73+
[query]({{< relref "/develop/ai/search-and-query/query" >}})
74+
below searches for objects that have the text "Paul" in any field
75+
and have an `age` value in the range 30 to 40:
76+
77+
{{< clients-example lettuce_home_json query1 >}}
78+
{{< /clients-example >}}
79+
80+
Specify query options to return only the `city` field:
81+
82+
{{< clients-example lettuce_home_json query2 >}}
83+
{{< /clients-example >}}
84+
85+
Use an
86+
[aggregation query]({{< relref "/develop/ai/search-and-query/query/aggregation" >}})
87+
to count all users in each city.
88+
89+
{{< clients-example lettuce_home_json query3 >}}
90+
{{< /clients-example >}}
91+
92+
## Differences with hash documents
93+
94+
Indexing for hash documents is very similar to JSON indexing but you
95+
need to specify some slightly different options.
96+
97+
When you create the schema for a hash index, you don't need to
98+
add aliases for the fields, since you use the basic names to access
99+
the fields. Also, you must use `CreateArgs.TargetType.HASH` for the `On()`
100+
option of `CreateArgs` when you create the index. The code below shows these
101+
changes with a new index called `hash-idx:users`, which is otherwise the same as
102+
the `idx:users` index used for JSON documents in the previous examples.
103+
104+
{{< clients-example lettuce_home_json make_hash_index >}}
105+
{{< /clients-example >}}
106+
107+
Use [`hset()`]({{< relref "/commands/hset" >}}) to add the hash
108+
documents instead of [`jsonSet()`]({{< relref "/commands/json.set" >}}).
109+
110+
{{< clients-example lettuce_home_json add_hash_data >}}
111+
{{< /clients-example >}}
112+
113+
The query commands work the same here for hash as they do for JSON (but
114+
the name of the hash index is different). The results are returned in
115+
a `List` of `SearchReply.SearchResult<String, String>` objects, as with JSON:
116+
117+
{{< clients-example lettuce_home_json query1_hash >}}
118+
{{< /clients-example >}}
119+
120+
## More information
121+
122+
See the [Redis query engine]({{< relref "/develop/ai/search-and-query" >}}) docs
123+
for a full description of all query features with examples.

content/develop/clients/redis-py/vecsets.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pip install sentence-transformers
4747

4848
In a new Python file, import the required classes:
4949

50-
{{< clients-example set="home_vecsets" step="import" >}}
50+
{{< clients-example set="home_vecsets" step="import" lang_filter="Python" >}}
5151
{{< /clients-example >}}
5252

5353
The first of these imports is the
@@ -61,15 +61,15 @@ tokens (see
6161
at the [Hugging Face](https://huggingface.co/) docs to learn more about the way tokens
6262
are related to the original text).
6363

64-
{{< clients-example set="home_vecsets" step="model" >}}
64+
{{< clients-example set="home_vecsets" step="model" lang_filter="Python" >}}
6565
{{< /clients-example >}}
6666

6767
## Create the data
6868

6969
The example data is contained a dictionary with some brief
7070
descriptions of famous people:
7171

72-
{{< clients-example set="home_vecsets" step="data" >}}
72+
{{< clients-example set="home_vecsets" step="data" lang_filter="Python" >}}
7373
{{< /clients-example >}}
7474

7575
## Add the data to a vector set
@@ -99,7 +99,7 @@ The call to `vadd()` also adds the `born` and `died` values from the
9999
original dictionary as attribute data. You can access this during a query
100100
or by using the [`vgetattr()`]({{< relref "/commands/vgetattr" >}}) method.
101101

102-
{{< clients-example set="home_vecsets" step="add_data" >}}
102+
{{< clients-example set="home_vecsets" step="add_data" lang_filter="Python" >}}
103103
{{< /clients-example >}}
104104

105105
## Query the vector set
@@ -112,7 +112,7 @@ of the set, ranked in order of similarity to the query.
112112

113113
Start with a simple query for "actors":
114114

115-
{{< clients-example set="home_vecsets" step="basic_query" >}}
115+
{{< clients-example set="home_vecsets" step="basic_query" lang_filter="Python" >}}
116116
{{< /clients-example >}}
117117

118118
This returns the following list of elements (formatted slightly for clarity):
@@ -131,7 +131,7 @@ on the information contained in the embedding model.
131131
You can use the `count` parameter of `vsim()` to limit the list of elements
132132
to just the most relevant few items:
133133

134-
{{< clients-example set="home_vecsets" step="limited_query" >}}
134+
{{< clients-example set="home_vecsets" step="limited_query" lang_filter="Python" >}}
135135
{{< /clients-example >}}
136136

137137
The reason for using text embeddings rather than simple text search
@@ -141,7 +141,7 @@ different. For example, the word "entertainer" doesn't appear in any of the
141141
descriptions but if you use it as a query, the actors and musicians are ranked
142142
highest in the results list:
143143

144-
{{< clients-example set="home_vecsets" step="entertainer_query" >}}
144+
{{< clients-example set="home_vecsets" step="entertainer_query" lang_filter="Python" >}}
145145
{{< /clients-example >}}
146146

147147
Similarly, if you use "science" as a query, you get the following results:
@@ -162,7 +162,7 @@ with `vsim()` to restrict the search further. For example,
162162
repeat the "science" query, but this time limit the results to people
163163
who died before the year 2000:
164164

165-
{{< clients-example set="home_vecsets" step="filtered_query" >}}
165+
{{< clients-example set="home_vecsets" step="filtered_query" lang_filter="Python" >}}
166166
{{< /clients-example >}}
167167

168168
Note that the boolean filter expression is applied to items in the list

0 commit comments

Comments
 (0)