Skip to content

Commit 22ef96e

Browse files
authored
RediSearch support (part 1 of 3) (#3325)
* Revert "Revert "Add support for FT.CREATE #2717 (#3150)" (#3160)" (#3161) This reverts commit 319e315. * Add support for FT.DROPINDEX #2722 (#3164) * Add support for FT.DROPINDEX #2722 * Polishing * FT.SEARCH added Vibe code the FT.SEARCH command Pulled latest from the integration branch Fixed a lot of the hallucinations RESP2 parser improvements JSON Indexing tests Add some advanced use-cases Fixed all integration tests Fixed schema fields, added vector tests, but they are all failing Fixed vector search tests Improve coverage of integration and unit tests One unit test fails * API cleanup, added Kotlin implementation * Implement the FT.AGGREGATE command Fixing the integration tests for FT.AGGREGATE Polishing 1/3 Add more documentation ot the AggregateArgs * Implement the FT.CURSOR command Add Integration tests for the FT.CURSOR Add RESP2 tests for all aggragation integration tests * FT.AGGREGATE was never working in the first place, now it is working, but for RESP3 only * Fixing unit tests (part1) Fixing unit tests (part2) Fixing unit tests (part3) * Polishing (part 1)
1 parent 371beb0 commit 22ef96e

File tree

69 files changed

+15929
-24
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+15929
-24
lines changed

.github/workflows/integration.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ on:
88
branches:
99
- main
1010
- '[0-9].*'
11+
- 'feature/*'
1112
pull_request:
1213
branches:
1314
- main
1415
- '[0-9].*'
16+
- 'feature/*'
1517
schedule:
1618
- cron: '0 1 * * *' # nightly build
1719
workflow_dispatch:

src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@
4848
import io.lettuce.core.protocol.CommandType;
4949
import io.lettuce.core.protocol.ProtocolKeyword;
5050
import io.lettuce.core.protocol.RedisCommand;
51+
import io.lettuce.core.search.AggregationReply;
52+
import io.lettuce.core.search.SearchReply;
53+
import io.lettuce.core.search.arguments.AggregateArgs;
54+
import io.lettuce.core.search.arguments.CreateArgs;
55+
import io.lettuce.core.search.arguments.FieldArgs;
56+
import io.lettuce.core.search.arguments.SearchArgs;
5157
import io.lettuce.core.vector.RawVector;
5258
import io.lettuce.core.vector.VectorMetadata;
5359

@@ -82,14 +88,16 @@ public abstract class AbstractRedisAsyncCommands<K, V> implements RedisAclAsyncC
8288
RedisSortedSetAsyncCommands<K, V>, RedisScriptingAsyncCommands<K, V>, RedisServerAsyncCommands<K, V>,
8389
RedisHLLAsyncCommands<K, V>, BaseRedisAsyncCommands<K, V>, RedisTransactionalAsyncCommands<K, V>,
8490
RedisGeoAsyncCommands<K, V>, RedisClusterAsyncCommands<K, V>, RedisJsonAsyncCommands<K, V>,
85-
RedisVectorSetAsyncCommands<K, V> {
91+
RedisVectorSetAsyncCommands<K, V>, RediSearchAsyncCommands<K, V> {
8692

8793
private final StatefulConnection<K, V> connection;
8894

8995
private final RedisCommandBuilder<K, V> commandBuilder;
9096

9197
private final RedisJsonCommandBuilder<K, V> jsonCommandBuilder;
9298

99+
private final RediSearchCommandBuilder<K, V> searchCommandBuilder;
100+
93101
private final RedisVectorSetCommandBuilder<K, V> vectorSetCommandBuilder;
94102

95103
private final Supplier<JsonParser> parser;
@@ -108,6 +116,7 @@ public AbstractRedisAsyncCommands(StatefulConnection<K, V> connection, RedisCode
108116
this.commandBuilder = new RedisCommandBuilder<>(codec);
109117
this.jsonCommandBuilder = new RedisJsonCommandBuilder<>(codec, parser);
110118
this.vectorSetCommandBuilder = new RedisVectorSetCommandBuilder<>(codec, parser);
119+
this.searchCommandBuilder = new RediSearchCommandBuilder<>(codec);
111120
}
112121

113122
/**
@@ -1540,6 +1549,61 @@ public boolean isOpen() {
15401549
return connection.isOpen();
15411550
}
15421551

1552+
@Override
1553+
public RedisFuture<String> ftCreate(K index, CreateArgs<K, V> options, List<FieldArgs<K>> fieldArgs) {
1554+
return dispatch(searchCommandBuilder.ftCreate(index, options, fieldArgs));
1555+
}
1556+
1557+
@Override
1558+
public RedisFuture<String> ftCreate(K index, List<FieldArgs<K>> fieldArgs) {
1559+
return dispatch(searchCommandBuilder.ftCreate(index, null, fieldArgs));
1560+
}
1561+
1562+
@Override
1563+
public RedisFuture<String> ftDropindex(K index, boolean deleteDocumentKeys) {
1564+
return dispatch(searchCommandBuilder.ftDropindex(index, deleteDocumentKeys));
1565+
}
1566+
1567+
@Override
1568+
public RedisFuture<String> ftDropindex(K index) {
1569+
return dispatch(searchCommandBuilder.ftDropindex(index, false));
1570+
}
1571+
1572+
@Override
1573+
public RedisFuture<SearchReply<K, V>> ftSearch(K index, V query, SearchArgs<K, V> args) {
1574+
return dispatch(searchCommandBuilder.ftSearch(index, query, args));
1575+
}
1576+
1577+
@Override
1578+
public RedisFuture<SearchReply<K, V>> ftSearch(K index, V query) {
1579+
return dispatch(searchCommandBuilder.ftSearch(index, query, SearchArgs.<K, V> builder().build()));
1580+
}
1581+
1582+
@Override
1583+
public RedisFuture<AggregationReply<K, V>> ftAggregate(K index, V query, AggregateArgs<K, V> args) {
1584+
return dispatch(searchCommandBuilder.ftAggregate(index, query, args));
1585+
}
1586+
1587+
@Override
1588+
public RedisFuture<AggregationReply<K, V>> ftAggregate(K index, V query) {
1589+
return dispatch(searchCommandBuilder.ftAggregate(index, query, null));
1590+
}
1591+
1592+
@Override
1593+
public RedisFuture<AggregationReply<K, V>> ftCursorread(K index, long cursorId, int count) {
1594+
return dispatch(searchCommandBuilder.ftCursorread(index, cursorId, count));
1595+
}
1596+
1597+
@Override
1598+
public RedisFuture<AggregationReply<K, V>> ftCursorread(K index, long cursorId) {
1599+
return dispatch(searchCommandBuilder.ftCursorread(index, cursorId, -1));
1600+
}
1601+
1602+
@Override
1603+
public RedisFuture<String> ftCursordel(K index, long cursorId) {
1604+
return dispatch(searchCommandBuilder.ftCursordel(index, cursorId));
1605+
}
1606+
15431607
@Override
15441608
public RedisFuture<List<Long>> jsonArrappend(K key, JsonPath jsonPath, JsonValue... values) {
15451609
return dispatch(jsonCommandBuilder.jsonArrappend(key, jsonPath, values));

src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java

Lines changed: 71 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@
4949
import io.lettuce.core.protocol.RedisCommand;
5050
import io.lettuce.core.protocol.TracedCommand;
5151
import io.lettuce.core.resource.ClientResources;
52+
import io.lettuce.core.search.AggregationReply;
53+
import io.lettuce.core.search.SearchReply;
54+
import io.lettuce.core.search.arguments.AggregateArgs;
55+
import io.lettuce.core.search.arguments.CreateArgs;
56+
import io.lettuce.core.search.arguments.FieldArgs;
57+
import io.lettuce.core.search.arguments.SearchArgs;
5258
import io.lettuce.core.tracing.TraceContext;
5359
import io.lettuce.core.tracing.TraceContextProvider;
5460
import io.lettuce.core.tracing.Tracing;
@@ -86,19 +92,22 @@
8692
* @author Tihomir Mateev
8793
* @since 4.0
8894
*/
89-
public abstract class AbstractRedisReactiveCommands<K, V> implements RedisAclReactiveCommands<K, V>,
90-
RedisHashReactiveCommands<K, V>, RedisKeyReactiveCommands<K, V>, RedisStringReactiveCommands<K, V>,
91-
RedisListReactiveCommands<K, V>, RedisSetReactiveCommands<K, V>, RedisSortedSetReactiveCommands<K, V>,
92-
RedisScriptingReactiveCommands<K, V>, RedisServerReactiveCommands<K, V>, RedisHLLReactiveCommands<K, V>,
93-
BaseRedisReactiveCommands<K, V>, RedisTransactionalReactiveCommands<K, V>, RedisGeoReactiveCommands<K, V>,
94-
RedisClusterReactiveCommands<K, V>, RedisJsonReactiveCommands<K, V>, RedisVectorSetReactiveCommands<K, V> {
95+
public abstract class AbstractRedisReactiveCommands<K, V>
96+
implements RedisAclReactiveCommands<K, V>, RedisHashReactiveCommands<K, V>, RedisKeyReactiveCommands<K, V>,
97+
RedisStringReactiveCommands<K, V>, RedisListReactiveCommands<K, V>, RedisSetReactiveCommands<K, V>,
98+
RedisSortedSetReactiveCommands<K, V>, RedisScriptingReactiveCommands<K, V>, RedisServerReactiveCommands<K, V>,
99+
RedisHLLReactiveCommands<K, V>, BaseRedisReactiveCommands<K, V>, RedisTransactionalReactiveCommands<K, V>,
100+
RedisGeoReactiveCommands<K, V>, RedisClusterReactiveCommands<K, V>, RedisJsonReactiveCommands<K, V>,
101+
RedisVectorSetReactiveCommands<K, V>, RediSearchReactiveCommands<K, V> {
95102

96103
private final StatefulConnection<K, V> connection;
97104

98105
private final RedisCommandBuilder<K, V> commandBuilder;
99106

100107
private final RedisJsonCommandBuilder<K, V> jsonCommandBuilder;
101108

109+
private final RediSearchCommandBuilder<K, V> searchCommandBuilder;
110+
102111
private final RedisVectorSetCommandBuilder<K, V> vectorSetCommandBuilder;
103112

104113
private final Supplier<JsonParser> parser;
@@ -123,6 +132,7 @@ public AbstractRedisReactiveCommands(StatefulConnection<K, V> connection, RedisC
123132
this.commandBuilder = new RedisCommandBuilder<>(codec);
124133
this.jsonCommandBuilder = new RedisJsonCommandBuilder<>(codec, parser);
125134
this.vectorSetCommandBuilder = new RedisVectorSetCommandBuilder<>(codec, parser);
135+
this.searchCommandBuilder = new RediSearchCommandBuilder<>(codec);
126136
this.clientResources = connection.getResources();
127137
this.tracingEnabled = clientResources.tracing().isEnabled();
128138
}
@@ -1604,6 +1614,61 @@ public boolean isOpen() {
16041614
return connection.isOpen();
16051615
}
16061616

1617+
@Override
1618+
public Mono<String> ftCreate(K index, CreateArgs<K, V> options, List<FieldArgs<K>> fieldArgs) {
1619+
return createMono(() -> searchCommandBuilder.ftCreate(index, options, fieldArgs));
1620+
}
1621+
1622+
@Override
1623+
public Mono<String> ftCreate(K index, List<FieldArgs<K>> fieldArgs) {
1624+
return createMono(() -> searchCommandBuilder.ftCreate(index, null, fieldArgs));
1625+
}
1626+
1627+
@Override
1628+
public Mono<String> ftCursordel(K index, long cursorId) {
1629+
return createMono(() -> searchCommandBuilder.ftCursordel(index, cursorId));
1630+
}
1631+
1632+
@Override
1633+
public Mono<String> ftDropindex(K index, boolean deleteDocumentKeys) {
1634+
return createMono(() -> searchCommandBuilder.ftDropindex(index, deleteDocumentKeys));
1635+
}
1636+
1637+
@Override
1638+
public Mono<String> ftDropindex(K index) {
1639+
return createMono(() -> searchCommandBuilder.ftDropindex(index, false));
1640+
}
1641+
1642+
@Override
1643+
public Mono<SearchReply<K, V>> ftSearch(K index, V query, SearchArgs<K, V> args) {
1644+
return createMono(() -> searchCommandBuilder.ftSearch(index, query, args));
1645+
}
1646+
1647+
@Override
1648+
public Mono<SearchReply<K, V>> ftSearch(K index, V query) {
1649+
return createMono(() -> searchCommandBuilder.ftSearch(index, query, SearchArgs.<K, V> builder().build()));
1650+
}
1651+
1652+
@Override
1653+
public Mono<AggregationReply<K, V>> ftAggregate(K index, V query, AggregateArgs<K, V> args) {
1654+
return createMono(() -> searchCommandBuilder.ftAggregate(index, query, args));
1655+
}
1656+
1657+
@Override
1658+
public Mono<AggregationReply<K, V>> ftAggregate(K index, V query) {
1659+
return createMono(() -> searchCommandBuilder.ftAggregate(index, query, null));
1660+
}
1661+
1662+
@Override
1663+
public Mono<AggregationReply<K, V>> ftCursorread(K index, long cursorId, int count) {
1664+
return createMono(() -> searchCommandBuilder.ftCursorread(index, cursorId, count));
1665+
}
1666+
1667+
@Override
1668+
public Mono<AggregationReply<K, V>> ftCursorread(K index, long cursorId) {
1669+
return createMono(() -> searchCommandBuilder.ftCursorread(index, cursorId, -1));
1670+
}
1671+
16071672
@Override
16081673
public Flux<Long> jsonArrappend(K key, JsonPath jsonPath, JsonValue... values) {
16091674
return createDissolvingFlux(() -> jsonCommandBuilder.jsonArrappend(key, jsonPath, values));

0 commit comments

Comments
 (0)