Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
816d6ac
fix: rework search API generics to replace unnecessary type params wi…
viktoriya-kutsarova Apr 7, 2026
5e1fbf3
fix: rework search API generics to replace unnecessary type params wi…
viktoriya-kutsarova Apr 20, 2026
c16f62f
Add verification tests
a-TODO-rov Apr 23, 2026
5df24e6
Expand codec verification tests and revert K for field names and INKEYS.
viktoriya-kutsarova Apr 30, 2026
6529416
Add more verification tests
a-TODO-rov May 8, 2026
b95bc21
Add more codec tests ana parametrize them.
viktoriya-kutsarova May 11, 2026
c6de9b4
Fix prefix issue.
viktoriya-kutsarova May 11, 2026
15fb97c
Fix params issue.
viktoriya-kutsarova May 12, 2026
3037c96
Add more tests for search on HASH using codec.
viktoriya-kutsarova May 12, 2026
9b2e6c4
Remove generics from FieldArgs and update all affected files.
viktoriya-kutsarova Jun 30, 2026
16afb0f
Remove generics from SugGetArgs and update all affected files.
viktoriya-kutsarova Jun 30, 2026
77d91e2
Remove generics from ftSugadd, ftSugdel, ftSugget, their params and u…
viktoriya-kutsarova Jul 1, 2026
8f35b27
Fix RESP2 inability to properly parse scores because they are sent as…
viktoriya-kutsarova Jul 1, 2026
0e7ac32
Remove generics from ftTagvals command and all affected files.
viktoriya-kutsarova Jul 1, 2026
236ffbd
Rework most of the generic fields in CreateArgs apart from the prefix…
viktoriya-kutsarova Jul 1, 2026
c1a77a4
Rework SearchArgs to remove K and V and all affected files.
viktoriya-kutsarova Jul 2, 2026
7293408
Rework AggregateArg to remove generics and all affected files.
viktoriya-kutsarova Jul 2, 2026
c9aa913
Rework HybridArgs to remove generics and fix all affected files.
viktoriya-kutsarova Jul 2, 2026
264f32e
Rework SearchReply and HybridReply to remove K and V generics where n…
viktoriya-kutsarova Jul 3, 2026
9c99a44
Remove phantom-V leftover from search module files.
viktoriya-kutsarova Jul 10, 2026
11df3ed
Fix issues with tests.
viktoriya-kutsarova Jul 10, 2026
c9867a5
Remove generic from withPrefix in CreateArgs and fix all affected files.
viktoriya-kutsarova Jul 21, 2026
bbfc004
Update redis-search docs.
viktoriya-kutsarova Jul 21, 2026
b132d54
Introduce FieldValue to allow for mixed types (vectors and strings) t…
viktoriya-kutsarova Jul 22, 2026
dfd56ad
Decode FT.HYBRID document keys with the connection codec.
viktoriya-kutsarova Jul 23, 2026
707feb2
Avoid raw cast of CommandOutput for ftSpellcheck.
viktoriya-kutsarova Aug 10, 2026
a605ccf
Rework FILTER codec-safety test around schema aliases.
viktoriya-kutsarova Aug 11, 2026
f5063dc
Remove templates
a-TODO-rov Aug 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ dependency-reduced-pom.xml
*.java-version
*.DS_Store
prDescription.md
.vscode*
.vscode*
.augment
331 changes: 158 additions & 173 deletions docs/user-guide/redis-search.md

Large diffs are not rendered by default.

66 changes: 33 additions & 33 deletions src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public abstract class AbstractRedisAsyncCommands<K, V> implements RedisAclAsyncC
RedisSortedSetAsyncCommands<K, V>, RedisScriptingAsyncCommands<K, V>, RedisServerAsyncCommands<K, V>,
RedisHLLAsyncCommands<K, V>, BaseRedisAsyncCommands<K, V>, RedisTransactionalAsyncCommands<K, V>,
RedisGeoAsyncCommands<K, V>, RedisClusterAsyncCommands<K, V>, RedisJsonAsyncCommands<K, V>,
RedisVectorSetAsyncCommands<K, V>, RediSearchAsyncCommands<K, V>, RedisArrayAsyncCommands<K, V>,
RedisVectorSetAsyncCommands<K, V>, RediSearchAsyncCommands<K>, RedisArrayAsyncCommands<K, V>,
RedisBloomFilterAsyncCommands<K, V>, RedisCuckooFilterAsyncCommands<K, V>, RedisTopKAsyncCommands<K, V>,
RedisCMSAsyncCommands<K, V>, RedisTDigestAsyncCommands<K, V> {

Expand Down Expand Up @@ -1725,12 +1725,12 @@ public RedisFuture<String> info(String section) {
}

@Override
public RedisFuture<String> ftCreate(String index, CreateArgs<K, V> options, List<FieldArgs<K>> fieldArgs) {
public RedisFuture<String> ftCreate(String index, CreateArgs options, List<FieldArgs> fieldArgs) {
return dispatch(searchCommandBuilder.ftCreate(index, options, fieldArgs));
}

@Override
public RedisFuture<String> ftCreate(String index, List<FieldArgs<K>> fieldArgs) {
public RedisFuture<String> ftCreate(String index, List<FieldArgs> fieldArgs) {
return dispatch(searchCommandBuilder.ftCreate(index, null, fieldArgs));
}

Expand All @@ -1755,92 +1755,92 @@ public RedisFuture<List<String>> ftAliaslist(String index) {
}

@Override
public RedisFuture<String> ftAlter(String index, boolean skipInitialScan, List<FieldArgs<K>> fieldArgs) {
public RedisFuture<String> ftAlter(String index, boolean skipInitialScan, List<FieldArgs> fieldArgs) {
return dispatch(searchCommandBuilder.ftAlter(index, skipInitialScan, fieldArgs));
}

@Override
public RedisFuture<List<V>> ftTagvals(String index, String fieldName) {
public RedisFuture<List<String>> ftTagvals(String index, String fieldName) {
return dispatch(searchCommandBuilder.ftTagvals(index, fieldName));
}

@Override
public RedisFuture<SpellCheckResult<V>> ftSpellcheck(String index, V query) {
public RedisFuture<SpellCheckResult> ftSpellcheck(String index, String query) {
return dispatch(searchCommandBuilder.ftSpellcheck(index, query));
}

@Override
public RedisFuture<SpellCheckResult<V>> ftSpellcheck(String index, V query, SpellCheckArgs<K, V> args) {
public RedisFuture<SpellCheckResult> ftSpellcheck(String index, String query, SpellCheckArgs args) {
return dispatch(searchCommandBuilder.ftSpellcheck(index, query, args));
}

@Override
public RedisFuture<Long> ftDictadd(String dict, V... terms) {
public RedisFuture<Long> ftDictadd(String dict, String... terms) {
return dispatch(searchCommandBuilder.ftDictadd(dict, terms));
}

@Override
public RedisFuture<Long> ftDictdel(String dict, V... terms) {
public RedisFuture<Long> ftDictdel(String dict, String... terms) {
return dispatch(searchCommandBuilder.ftDictdel(dict, terms));
}

@Override
public RedisFuture<List<V>> ftDictdump(String dict) {
public RedisFuture<List<String>> ftDictdump(String dict) {
return dispatch(searchCommandBuilder.ftDictdump(dict));
}

@Override
public RedisFuture<String> ftExplain(String index, V query) {
public RedisFuture<String> ftExplain(String index, String query) {
return dispatch(searchCommandBuilder.ftExplain(index, query));
}

@Override
public RedisFuture<String> ftExplain(String index, V query, ExplainArgs<K, V> args) {
public RedisFuture<String> ftExplain(String index, String query, ExplainArgs args) {
return dispatch(searchCommandBuilder.ftExplain(index, query, args));
}

@Override
public RedisFuture<List<V>> ftList() {
public RedisFuture<List<String>> ftList() {
return dispatch(searchCommandBuilder.ftList());
}

@Override
public RedisFuture<Map<V, List<V>>> ftSyndump(String index) {
public RedisFuture<Map<String, List<String>>> ftSyndump(String index) {
return dispatch(searchCommandBuilder.ftSyndump(index));
}

@Override
public RedisFuture<String> ftSynupdate(String index, V synonymGroupId, V... terms) {
public RedisFuture<String> ftSynupdate(String index, String synonymGroupId, String... terms) {
return dispatch(searchCommandBuilder.ftSynupdate(index, synonymGroupId, terms));
}

@Override
public RedisFuture<String> ftSynupdate(String index, V synonymGroupId, SynUpdateArgs<K, V> args, V... terms) {
public RedisFuture<String> ftSynupdate(String index, String synonymGroupId, SynUpdateArgs args, String... terms) {
return dispatch(searchCommandBuilder.ftSynupdate(index, synonymGroupId, args, terms));
}

@Override
public RedisFuture<Long> ftSugadd(K key, V string, double score) {
return dispatch(searchCommandBuilder.ftSugadd(key, string, score));
public RedisFuture<Long> ftSugadd(K key, String suggestion, double score) {
return dispatch(searchCommandBuilder.ftSugadd(key, suggestion, score));
}

@Override
public RedisFuture<Long> ftSugadd(K key, V string, double score, SugAddArgs<K, V> args) {
return dispatch(searchCommandBuilder.ftSugadd(key, string, score, args));
public RedisFuture<Long> ftSugadd(K key, String suggestion, double score, SugAddArgs args) {
return dispatch(searchCommandBuilder.ftSugadd(key, suggestion, score, args));
}

@Override
public RedisFuture<Boolean> ftSugdel(K key, V string) {
return dispatch(searchCommandBuilder.ftSugdel(key, string));
public RedisFuture<Boolean> ftSugdel(K key, String suggestion) {
return dispatch(searchCommandBuilder.ftSugdel(key, suggestion));
}

@Override
public RedisFuture<List<Suggestion<V>>> ftSugget(K key, V prefix) {
public RedisFuture<List<Suggestion>> ftSugget(K key, String prefix) {
return dispatch(searchCommandBuilder.ftSugget(key, prefix));
}

@Override
public RedisFuture<List<Suggestion<V>>> ftSugget(K key, V prefix, SugGetArgs<K, V> args) {
public RedisFuture<List<Suggestion>> ftSugget(K key, String prefix, SugGetArgs args) {
return dispatch(searchCommandBuilder.ftSugget(key, prefix, args));
}

Expand All @@ -1850,7 +1850,7 @@ public RedisFuture<Long> ftSuglen(K key) {
}

@Override
public RedisFuture<String> ftAlter(String index, List<FieldArgs<K>> fieldArgs) {
public RedisFuture<String> ftAlter(String index, List<FieldArgs> fieldArgs) {
return dispatch(searchCommandBuilder.ftAlter(index, false, fieldArgs));
}

Expand All @@ -1865,32 +1865,32 @@ public RedisFuture<String> ftDropindex(String index) {
}

@Override
public RedisFuture<SearchReply<K, V>> ftSearch(String index, V query, SearchArgs<K, V> args) {
public RedisFuture<SearchReply<K>> ftSearch(String index, String query, SearchArgs<K> args) {
return dispatch(searchCommandBuilder.ftSearch(index, query, args));
}

@Override
public RedisFuture<SearchReply<K, V>> ftSearch(String index, V query) {
return dispatch(searchCommandBuilder.ftSearch(index, query, SearchArgs.<K, V> builder().build()));
public RedisFuture<SearchReply<K>> ftSearch(String index, String query) {
return dispatch(searchCommandBuilder.ftSearch(index, query, SearchArgs.<K> builder().build()));
}

@Override
public RedisFuture<HybridReply<K, V>> ftHybrid(String index, HybridArgs<K, V> args) {
public RedisFuture<HybridReply<K>> ftHybrid(String index, HybridArgs args) {
return dispatch(searchCommandBuilder.ftHybrid(index, args));
}

@Override
public RedisFuture<AggregationReply<K, V>> ftAggregate(String index, V query, AggregateArgs<K, V> args) {
public RedisFuture<AggregationReply<K>> ftAggregate(String index, String query, AggregateArgs args) {
return dispatch(searchCommandBuilder.ftAggregate(index, query, args));
}

@Override
public RedisFuture<AggregationReply<K, V>> ftAggregate(String index, V query) {
public RedisFuture<AggregationReply<K>> ftAggregate(String index, String query) {
return dispatch(searchCommandBuilder.ftAggregate(index, query, null));
}

@Override
public RedisFuture<AggregationReply<K, V>> ftCursorread(String index, Cursor cursor, int count) {
public RedisFuture<AggregationReply<K>> ftCursorread(String index, Cursor cursor, int count) {
if (cursor == null) {
throw new IllegalArgumentException("cursor must not be null");
}
Expand All @@ -1899,7 +1899,7 @@ public RedisFuture<AggregationReply<K, V>> ftCursorread(String index, Cursor cur
}

@Override
public RedisFuture<AggregationReply<K, V>> ftCursorread(String index, Cursor cursor) {
public RedisFuture<AggregationReply<K>> ftCursorread(String index, Cursor cursor) {
return ftCursorread(index, cursor, -1);
}

Expand Down
66 changes: 33 additions & 33 deletions src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ public abstract class AbstractRedisReactiveCommands<K, V>
RedisSortedSetReactiveCommands<K, V>, RedisScriptingReactiveCommands<K, V>, RedisServerReactiveCommands<K, V>,
RedisHLLReactiveCommands<K, V>, BaseRedisReactiveCommands<K, V>, RedisTransactionalReactiveCommands<K, V>,
RedisGeoReactiveCommands<K, V>, RedisClusterReactiveCommands<K, V>, RedisJsonReactiveCommands<K, V>,
RedisVectorSetReactiveCommands<K, V>, RediSearchReactiveCommands<K, V>, RedisArrayReactiveCommands<K, V>,
RedisVectorSetReactiveCommands<K, V>, RediSearchReactiveCommands<K>, RedisArrayReactiveCommands<K, V>,
RedisBloomFilterReactiveCommands<K, V>, RedisCuckooFilterReactiveCommands<K, V>, RedisTopKReactiveCommands<K, V>,
RedisCMSReactiveCommands<K, V>, RedisTDigestReactiveCommands<K, V> {

Expand Down Expand Up @@ -1762,12 +1762,12 @@ public Mono<String> info(String section) {
}

@Override
public Mono<String> ftCreate(String index, CreateArgs<K, V> options, List<FieldArgs<K>> fieldArgs) {
public Mono<String> ftCreate(String index, CreateArgs options, List<FieldArgs> fieldArgs) {
return createMono(() -> searchCommandBuilder.ftCreate(index, options, fieldArgs));
}

@Override
public Mono<String> ftCreate(String index, List<FieldArgs<K>> fieldArgs) {
public Mono<String> ftCreate(String index, List<FieldArgs> fieldArgs) {
return createMono(() -> searchCommandBuilder.ftCreate(index, null, fieldArgs));
}

Expand All @@ -1792,92 +1792,92 @@ public Flux<String> ftAliaslist(String index) {
}

@Override
public Mono<String> ftAlter(String index, boolean skipInitialScan, List<FieldArgs<K>> fieldArgs) {
public Mono<String> ftAlter(String index, boolean skipInitialScan, List<FieldArgs> fieldArgs) {
return createMono(() -> searchCommandBuilder.ftAlter(index, skipInitialScan, fieldArgs));
}

@Override
public Flux<V> ftTagvals(String index, String fieldName) {
public Flux<String> ftTagvals(String index, String fieldName) {
return createDissolvingFlux(() -> searchCommandBuilder.ftTagvals(index, fieldName));
}

@Override
public Mono<SpellCheckResult<V>> ftSpellcheck(String index, V query) {
public Mono<SpellCheckResult> ftSpellcheck(String index, String query) {
return createMono(() -> searchCommandBuilder.ftSpellcheck(index, query));
}

@Override
public Mono<SpellCheckResult<V>> ftSpellcheck(String index, V query, SpellCheckArgs<K, V> args) {
public Mono<SpellCheckResult> ftSpellcheck(String index, String query, SpellCheckArgs args) {
return createMono(() -> searchCommandBuilder.ftSpellcheck(index, query, args));
}

@Override
public Mono<Long> ftDictadd(String dict, V... terms) {
public Mono<Long> ftDictadd(String dict, String... terms) {
return createMono(() -> searchCommandBuilder.ftDictadd(dict, terms));
}

@Override
public Mono<Long> ftDictdel(String dict, V... terms) {
public Mono<Long> ftDictdel(String dict, String... terms) {
return createMono(() -> searchCommandBuilder.ftDictdel(dict, terms));
}

@Override
public Flux<V> ftDictdump(String dict) {
public Flux<String> ftDictdump(String dict) {
return createDissolvingFlux(() -> searchCommandBuilder.ftDictdump(dict));
}

@Override
public Mono<String> ftExplain(String index, V query) {
public Mono<String> ftExplain(String index, String query) {
return createMono(() -> searchCommandBuilder.ftExplain(index, query));
}

@Override
public Mono<String> ftExplain(String index, V query, ExplainArgs<K, V> args) {
public Mono<String> ftExplain(String index, String query, ExplainArgs args) {
return createMono(() -> searchCommandBuilder.ftExplain(index, query, args));
}

@Override
public Flux<V> ftList() {
public Flux<String> ftList() {
return createDissolvingFlux(() -> searchCommandBuilder.ftList());
}

@Override
public Mono<Map<V, List<V>>> ftSyndump(String index) {
public Mono<Map<String, List<String>>> ftSyndump(String index) {
return createMono(() -> searchCommandBuilder.ftSyndump(index));
}

@Override
public Mono<String> ftSynupdate(String index, V synonymGroupId, V... terms) {
public Mono<String> ftSynupdate(String index, String synonymGroupId, String... terms) {
return createMono(() -> searchCommandBuilder.ftSynupdate(index, synonymGroupId, terms));
}

@Override
public Mono<String> ftSynupdate(String index, V synonymGroupId, SynUpdateArgs<K, V> args, V... terms) {
public Mono<String> ftSynupdate(String index, String synonymGroupId, SynUpdateArgs args, String... terms) {
return createMono(() -> searchCommandBuilder.ftSynupdate(index, synonymGroupId, args, terms));
}

@Override
public Mono<Long> ftSugadd(K key, V string, double score) {
return createMono(() -> searchCommandBuilder.ftSugadd(key, string, score));
public Mono<Long> ftSugadd(K key, String suggestion, double score) {
return createMono(() -> searchCommandBuilder.ftSugadd(key, suggestion, score));
}

@Override
public Mono<Long> ftSugadd(K key, V string, double score, SugAddArgs<K, V> args) {
return createMono(() -> searchCommandBuilder.ftSugadd(key, string, score, args));
public Mono<Long> ftSugadd(K key, String suggestion, double score, SugAddArgs args) {
return createMono(() -> searchCommandBuilder.ftSugadd(key, suggestion, score, args));
}

@Override
public Mono<Boolean> ftSugdel(K key, V string) {
return createMono(() -> searchCommandBuilder.ftSugdel(key, string));
public Mono<Boolean> ftSugdel(K key, String suggestion) {
return createMono(() -> searchCommandBuilder.ftSugdel(key, suggestion));
}

@Override
public Flux<Suggestion<V>> ftSugget(K key, V prefix) {
public Flux<Suggestion> ftSugget(K key, String prefix) {
return createDissolvingFlux(() -> searchCommandBuilder.ftSugget(key, prefix));
}

@Override
public Flux<Suggestion<V>> ftSugget(K key, V prefix, SugGetArgs<K, V> args) {
public Flux<Suggestion> ftSugget(K key, String prefix, SugGetArgs args) {
return createDissolvingFlux(() -> searchCommandBuilder.ftSugget(key, prefix, args));
}

Expand All @@ -1887,7 +1887,7 @@ public Mono<Long> ftSuglen(K key) {
}

@Override
public Mono<String> ftAlter(String index, List<FieldArgs<K>> fieldArgs) {
public Mono<String> ftAlter(String index, List<FieldArgs> fieldArgs) {
return createMono(() -> searchCommandBuilder.ftAlter(index, false, fieldArgs));
}

Expand All @@ -1913,32 +1913,32 @@ public Mono<String> ftDropindex(String index) {
}

@Override
public Mono<SearchReply<K, V>> ftSearch(String index, V query, SearchArgs<K, V> args) {
public Mono<SearchReply<K>> ftSearch(String index, String query, SearchArgs<K> args) {
return createMono(() -> searchCommandBuilder.ftSearch(index, query, args));
}

@Override
public Mono<SearchReply<K, V>> ftSearch(String index, V query) {
return createMono(() -> searchCommandBuilder.ftSearch(index, query, SearchArgs.<K, V> builder().build()));
public Mono<SearchReply<K>> ftSearch(String index, String query) {
return createMono(() -> searchCommandBuilder.ftSearch(index, query, SearchArgs.<K> builder().build()));
}

@Override
public Mono<HybridReply<K, V>> ftHybrid(String index, HybridArgs<K, V> args) {
public Mono<HybridReply<K>> ftHybrid(String index, HybridArgs args) {
return createMono(() -> searchCommandBuilder.ftHybrid(index, args));
}

@Override
public Mono<AggregationReply<K, V>> ftAggregate(String index, V query, AggregateArgs<K, V> args) {
public Mono<AggregationReply<K>> ftAggregate(String index, String query, AggregateArgs args) {
return createMono(() -> searchCommandBuilder.ftAggregate(index, query, args));
}

@Override
public Mono<AggregationReply<K, V>> ftAggregate(String index, V query) {
public Mono<AggregationReply<K>> ftAggregate(String index, String query) {
return createMono(() -> searchCommandBuilder.ftAggregate(index, query, null));
}

@Override
public Mono<AggregationReply<K, V>> ftCursorread(String index, Cursor cursor, int count) {
public Mono<AggregationReply<K>> ftCursorread(String index, Cursor cursor, int count) {
return createMono(() -> {
if (cursor == null) {
throw new IllegalArgumentException("cursor must not be null");
Expand All @@ -1949,7 +1949,7 @@ public Mono<AggregationReply<K, V>> ftCursorread(String index, Cursor cursor, in
}

@Override
public Mono<AggregationReply<K, V>> ftCursorread(String index, Cursor cursor) {
public Mono<AggregationReply<K>> ftCursorread(String index, Cursor cursor) {
return ftCursorread(index, cursor, -1);
}

Expand Down
Loading
Loading