Skip to content

Commit 65bfce5

Browse files
DOC-5556 updated local examples build and added Lettuce reactive examples
1 parent 1fe05d9 commit 65bfce5

File tree

2 files changed

+268
-2
lines changed

2 files changed

+268
-2
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: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
// EXAMPLE: lettuce_home_json
2+
package io.redis.examples.reactive;
3+
4+
// STEP_START import
5+
import io.lettuce.core.*;
6+
7+
import io.lettuce.core.api.reactive.RedisReactiveCommands;
8+
import io.lettuce.core.api.reactive.RediSearchReactiveCommands;
9+
import io.lettuce.core.search.arguments.*;
10+
import io.lettuce.core.search.arguments.AggregateArgs.*;
11+
import io.lettuce.core.search.SearchReply;
12+
import io.lettuce.core.search.AggregationReply;
13+
14+
import io.lettuce.core.json.JsonParser;
15+
import io.lettuce.core.json.JsonObject;
16+
import io.lettuce.core.json.JsonPath;
17+
18+
import io.lettuce.core.api.StatefulRedisConnection;
19+
20+
import java.util.*;
21+
import reactor.core.publisher.Mono;
22+
// STEP_END
23+
// REMOVE_START
24+
import org.junit.jupiter.api.Test;
25+
26+
import static org.assertj.core.api.Assertions.assertThat;
27+
// REMOVE_END
28+
29+
public class HomeJsonExample {
30+
31+
@Test
32+
public void run() {
33+
// STEP_START connect
34+
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
35+
36+
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
37+
RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();
38+
RediSearchReactiveCommands<String, String> searchCommands = connection.reactive();
39+
// ...
40+
// STEP_END
41+
// REMOVE_START
42+
reactiveCommands.del("user:1", "user:2", "user:3", "huser:1", "huser:2", "huser:3").block();
43+
searchCommands.ftDropindex("idx:users").onErrorReturn("Index `idx:users` does not exist").block();
44+
searchCommands.ftDropindex("hash-idx:users").onErrorReturn("Index `hash-idx:users` does not exist").block();
45+
// REMOVE_END
46+
47+
// STEP_START create_data
48+
JsonParser parser = reactiveCommands.getJsonParser();
49+
JsonObject user1 = parser.createJsonObject().put("name", parser.createJsonValue("\"Paul John\""))
50+
.put("email", parser.createJsonValue("\"[email protected]\"")).put("age", parser.createJsonValue("42"))
51+
.put("city", parser.createJsonValue("\"London\""));
52+
53+
JsonObject user2 = parser.createJsonObject().put("name", parser.createJsonValue("\"Eden Zamir\""))
54+
.put("email", parser.createJsonValue("\"[email protected]\"")).put("age", parser.createJsonValue("29"))
55+
.put("city", parser.createJsonValue("\"Tel Aviv\""));
56+
57+
JsonObject user3 = parser.createJsonObject().put("name", parser.createJsonValue("\"Paul Zamir\""))
58+
.put("email", parser.createJsonValue("\"[email protected]\"")).put("age", parser.createJsonValue("35"))
59+
.put("city", parser.createJsonValue("\"Tel Aviv\""));
60+
// STEP_END
61+
62+
// STEP_START make_index
63+
List<FieldArgs<String>> schema = Arrays.asList(TextFieldArgs.<String> builder().name("$.name").as("name").build(),
64+
NumericFieldArgs.<String> builder().name("$.age").as("age").build(),
65+
TagFieldArgs.<String> builder().name("$.city").as("city").build());
66+
67+
CreateArgs<String, String> createArgs = CreateArgs.<String, String> builder().on(CreateArgs.TargetType.JSON)
68+
.withPrefix("user:").build();
69+
70+
Mono<Void> make_index = searchCommands.ftCreate("idx:users", createArgs, schema).doOnNext(res -> {
71+
// REMOVE_START
72+
assertThat(res).isEqualTo("OK");
73+
// REMOVE_END
74+
System.out.println(res); // >>> OK
75+
}).then();
76+
// STEP_END
77+
make_index.block();
78+
79+
// STEP_START add_data
80+
Mono<String> addUser1 = reactiveCommands.jsonSet("user:1", JsonPath.ROOT_PATH, user1).doOnNext(r -> {
81+
System.out.println(r); // >>> OK
82+
// REMOVE_START
83+
assertThat(r).isEqualTo("OK");
84+
// REMOVE_END
85+
});
86+
87+
Mono<String> addUser2 = reactiveCommands.jsonSet("user:2", JsonPath.ROOT_PATH, user2).doOnNext(r -> {
88+
System.out.println(r); // >>> OK
89+
// REMOVE_START
90+
assertThat(r).isEqualTo("OK");
91+
// REMOVE_END
92+
});
93+
94+
Mono<String> addUser3 = reactiveCommands.jsonSet("user:3", JsonPath.ROOT_PATH, user3).doOnNext(r -> {
95+
System.out.println(r); // >>> OK
96+
// REMOVE_START
97+
assertThat(r).isEqualTo("OK");
98+
// REMOVE_END
99+
});
100+
// STEP_END
101+
Mono.when(addUser1, addUser2, addUser3).block();
102+
103+
// STEP_START query1
104+
Mono<SearchReply<String, String>> query1 = searchCommands.ftSearch("idx:users", "Paul @age:[30 40]")
105+
.doOnNext(res -> {
106+
List<SearchReply.SearchResult<String, String>> results = res.getResults();
107+
108+
results.forEach(result -> {
109+
System.out.println(result.getId());
110+
});
111+
// >>> user:3
112+
// REMOVE_START
113+
assertThat(res.getCount()).isEqualTo(1);
114+
assertThat(results.get(0).getId()).isEqualTo("user:3");
115+
// REMOVE_END
116+
});
117+
// STEP_END
118+
119+
// STEP_START query2
120+
SearchArgs<String, String> query2Args = SearchArgs.<String, String> builder().returnField("city").build();
121+
122+
Mono<SearchReply<String, String>> query2 = searchCommands.ftSearch("idx:users", "Paul", query2Args)
123+
.doOnNext(res -> {
124+
List<SearchReply.SearchResult<String, String>> results = res.getResults();
125+
126+
results.forEach(result -> {
127+
System.out.printf("ID: %s, City: %s\n", result.getId(), result.getFields().get("city"));
128+
});
129+
// >>> ID: user:1, City: London
130+
// >>> ID: user:3, City: Tel Aviv
131+
// REMOVE_START
132+
assertThat(res.getCount()).isEqualTo(2);
133+
assertThat(results.stream().map(result -> {
134+
return String.format("ID: %s, City: %s", result.getId(), result.getFields().get("city"));
135+
}).sorted().toArray()).containsExactly("ID: user:1, City: London", "ID: user:3, City: Tel Aviv");
136+
// REMOVE_END
137+
});
138+
// STEP_END
139+
140+
// STEP_START query3
141+
AggregateArgs<String, String> aggArgs = AggregateArgs.<String, String> builder()
142+
.groupBy(GroupBy.<String, String> of("@city").reduce(Reducer.<String, String> count().as("count"))).build();
143+
144+
Mono<AggregationReply<String, String>> query3 = searchCommands.ftAggregate("idx:users", "*", aggArgs)
145+
.doOnNext(res -> {
146+
List<SearchReply<String, String>> replies = res.getReplies();
147+
replies.forEach(reply -> {
148+
reply.getResults().forEach(result -> {
149+
System.out.printf("City: %s, Count: %s\n", result.getFields().get("city"),
150+
result.getFields().get("count"));
151+
});
152+
// >>> City: London, Count: 1
153+
// >>> City: Tel Aviv, Count: 2
154+
});
155+
// REMOVE_START
156+
assertThat(replies.size()).isEqualTo(1);
157+
assertThat(replies.get(0).getResults().size()).isEqualTo(2);
158+
assertThat(replies.get(0).getResults().stream().map(result -> {
159+
return String.format("City: %s, Count: %s", result.getFields().get("city"),
160+
result.getFields().get("count"));
161+
}).sorted().toArray()).containsExactly("City: London, Count: 1", "City: Tel Aviv, Count: 2");
162+
// REMOVE_END
163+
});
164+
// STEP_END
165+
166+
Mono.when(query1, query2, query3).block();
167+
168+
// STEP_START make_hash_index
169+
List<FieldArgs<String>> hashSchema = Arrays.asList(TextFieldArgs.<String> builder().name("name").build(),
170+
NumericFieldArgs.<String> builder().name("age").build(),
171+
TagFieldArgs.<String> builder().name("city").build());
172+
173+
CreateArgs<String, String> hashCreateArgs = CreateArgs.<String, String> builder().on(CreateArgs.TargetType.HASH)
174+
.withPrefix("huser:").build();
175+
176+
Mono<String> makeHashIndex = searchCommands.ftCreate("hash-idx:users", hashCreateArgs, hashSchema).doOnNext(res -> {
177+
// REMOVE_START
178+
assertThat(res).isEqualTo("OK");
179+
// REMOVE_END
180+
System.out.println(res); // >>> OK
181+
});
182+
// STEP_END
183+
makeHashIndex.block();
184+
185+
// STEP_START add_hash_data
186+
Map<String, String> huser1 = new HashMap<>();
187+
huser1.put("name", "Paul John");
188+
huser1.put("email", "[email protected]");
189+
huser1.put("age", "42");
190+
huser1.put("city", "London");
191+
192+
Map<String, String> huser2 = new HashMap<>();
193+
huser2.put("name", "Eden Zamir");
194+
huser2.put("email", "[email protected]");
195+
huser2.put("age", "29");
196+
huser2.put("city", "Tel Aviv");
197+
198+
Map<String, String> huser3 = new HashMap<>();
199+
huser3.put("name", "Paul Zamir");
200+
huser3.put("email", "[email protected]");
201+
huser3.put("age", "35");
202+
huser3.put("city", "Tel Aviv");
203+
204+
Mono<Long> addHashUser1 = reactiveCommands.hset("huser:1", huser1).doOnNext(r -> {
205+
System.out.println(r); // >>> OK
206+
// REMOVE_START
207+
assertThat(r).isEqualTo(4L);
208+
// REMOVE_END
209+
});
210+
211+
Mono<Long> addHashUser2 = reactiveCommands.hset("huser:2", huser2).doOnNext(r -> {
212+
System.out.println(r); // >>> OK
213+
// REMOVE_START
214+
assertThat(r).isEqualTo(4L);
215+
// REMOVE_END
216+
});
217+
218+
Mono<Long> addHashUser3 = reactiveCommands.hset("huser:3", huser3).doOnNext(r -> {
219+
System.out.println(r); // >>> OK
220+
// REMOVE_START
221+
assertThat(r).isEqualTo(4L);
222+
// REMOVE_END
223+
});
224+
// STEP_END
225+
Mono.when(addHashUser1, addHashUser2, addHashUser3).block();
226+
227+
// STEP_START query1_hash
228+
Mono<SearchReply<String, String>> query1Hash = searchCommands.ftSearch("hash-idx:users", "Paul @age:[30 40]")
229+
.doOnNext(res -> {
230+
List<SearchReply.SearchResult<String, String>> results = res.getResults();
231+
232+
results.forEach(result -> {
233+
System.out.println(result.getId());
234+
});
235+
// >>> huser:3
236+
// REMOVE_START
237+
assertThat(res.getCount()).isEqualTo(1);
238+
assertThat(results.get(0).getId()).isEqualTo("huser:3");
239+
// REMOVE_END
240+
});
241+
// STEP_END
242+
query1Hash.block();
243+
} finally {
244+
redisClient.shutdown();
245+
}
246+
}
247+
248+
}

0 commit comments

Comments
 (0)