Skip to content

Commit 99a1de3

Browse files
committed
Feature - RSearch.hybridSearch() method added. #6922
1 parent 07376ea commit 99a1de3

9 files changed

Lines changed: 290 additions & 14 deletions

File tree

redisson/src/main/java/org/redisson/RedissonSearch.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,14 +1239,14 @@ public RFuture<HybridSearchResult> hybridSearchAsync(String indexName, HybridQue
12391239
}
12401240

12411241
if (options.getGroupBy() != null) {
1242-
for (GroupBy groupBy : options.getGroupBy()) {
1243-
GroupParams groupParams = (GroupParams) groupBy;
1242+
for (org.redisson.api.search.GroupBy groupBy : options.getGroupBy()) {
1243+
org.redisson.api.search.GroupParams groupParams = (org.redisson.api.search.GroupParams) groupBy;
12441244
cmdArgs.add("GROUPBY");
12451245
cmdArgs.add(groupParams.getFieldNames().size());
12461246
cmdArgs.addAll(groupParams.getFieldNames());
12471247
if (groupParams.getReducers() != null) {
1248-
for (Reducer reducer : groupParams.getReducers()) {
1249-
ReducerParams reducerParams = (ReducerParams) reducer;
1248+
for (org.redisson.api.search.Reducer reducer : groupParams.getReducers()) {
1249+
org.redisson.api.search.ReducerParams reducerParams = (org.redisson.api.search.ReducerParams) reducer;
12501250
cmdArgs.add("REDUCE");
12511251
cmdArgs.add(reducerParams.getFunctionName());
12521252
cmdArgs.add(reducerParams.getArgs().size());
@@ -1263,7 +1263,7 @@ public RFuture<HybridSearchResult> hybridSearchAsync(String indexName, HybridQue
12631263
}
12641264

12651265
if (options.getExpressions() != null) {
1266-
for (Expression expr : options.getExpressions()) {
1266+
for (org.redisson.api.search.Expression expr : options.getExpressions()) {
12671267
cmdArgs.add("APPLY");
12681268
cmdArgs.add(expr.getValue());
12691269
cmdArgs.add("AS");
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* Copyright (c) 2013-2024 Nikita Koksharov
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.redisson.api.search;
17+
18+
/**
19+
* Expression that is applied on properties
20+
*
21+
* @author Nikita Koksharov
22+
*
23+
*/
24+
public final class Expression {
25+
26+
private final String value;
27+
private final String as;
28+
29+
public Expression(String expression, String as) {
30+
this.value = expression;
31+
this.as = as;
32+
}
33+
34+
public String getValue() {
35+
return value;
36+
}
37+
38+
public String getAs() {
39+
return as;
40+
}
41+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* Copyright (c) 2013-2024 Nikita Koksharov
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.redisson.api.search;
17+
18+
import java.util.Arrays;
19+
20+
/**
21+
*
22+
* @author Nikita Koksharov
23+
*
24+
*/
25+
public interface GroupBy {
26+
27+
/**
28+
* Defines field names used to group.
29+
*
30+
* @param names field names
31+
* @return config object
32+
*/
33+
static GroupBy fieldNames(String... names) {
34+
return new GroupParams(Arrays.asList(names));
35+
}
36+
37+
/**
38+
* Defines reducer objects.
39+
*
40+
* @param reducers reducer objects
41+
* @return config object
42+
*/
43+
GroupBy reducers(Reducer... reducers);
44+
45+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* Copyright (c) 2013-2024 Nikita Koksharov
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.redisson.api.search;
17+
18+
import java.util.Arrays;
19+
import java.util.Collections;
20+
import java.util.List;
21+
22+
/**
23+
*
24+
* @author Nikita Koksharov
25+
*
26+
*/
27+
public final class GroupParams implements GroupBy {
28+
29+
private List<String> fieldNames;
30+
private List<Reducer> reducers = Collections.emptyList();
31+
32+
GroupParams(List<String> fieldNames) {
33+
this.fieldNames = fieldNames;
34+
}
35+
36+
@Override
37+
public GroupBy reducers(Reducer... reducers) {
38+
this.reducers = Arrays.asList(reducers);
39+
return this;
40+
}
41+
42+
public List<String> getFieldNames() {
43+
return fieldNames;
44+
}
45+
46+
public List<Reducer> getReducers() {
47+
return reducers;
48+
}
49+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/**
2+
* Copyright (c) 2013-2024 Nikita Koksharov
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.redisson.api.search;
17+
18+
import org.redisson.api.SortOrder;
19+
import org.redisson.api.search.aggregate.AggregationOptions;
20+
21+
/**
22+
* Reducer object
23+
*
24+
* @author Nikita Koksharov
25+
*
26+
*/
27+
public interface Reducer {
28+
29+
static Reducer avg(String fieldName) {
30+
return new ReducerParams("AVG", fieldName);
31+
}
32+
33+
static Reducer sum(String fieldName) {
34+
return new ReducerParams("SUM", fieldName);
35+
}
36+
37+
static Reducer max(String fieldName) {
38+
return new ReducerParams("MAX", fieldName);
39+
}
40+
41+
static Reducer min(String fieldName) {
42+
return new ReducerParams("MIN", fieldName);
43+
}
44+
45+
static Reducer quantile(String fieldName, Double percent) {
46+
return new ReducerParams("QUANTILE", fieldName, percent.toString());
47+
}
48+
49+
static Reducer count() {
50+
return new ReducerParams("COUNT");
51+
}
52+
53+
static Reducer countDistinct(String fieldName) {
54+
return new ReducerParams("COUNT", fieldName);
55+
}
56+
57+
static Reducer countDistinctish(String fieldName) {
58+
return new ReducerParams("COUNT_DISTINCTISH", fieldName);
59+
}
60+
61+
static Reducer firstValue(String fieldName) {
62+
return new ReducerParams("FIRST_VALUE", fieldName);
63+
}
64+
65+
static Reducer firstValue(String fieldName, String sortFieldName, SortOrder sortOrder) {
66+
return new ReducerParams("FIRST_VALUE", fieldName, "BY", sortFieldName, sortOrder.toString());
67+
}
68+
69+
static Reducer randomSample(String fieldName, int size) {
70+
return new ReducerParams("FIRST_VALUE", fieldName, Integer.toString(size));
71+
}
72+
73+
static Reducer stddev(String fieldName) {
74+
return new ReducerParams("STDDEV", fieldName);
75+
}
76+
77+
static Reducer toList(String fieldName) {
78+
return new ReducerParams("TOLIST", fieldName);
79+
}
80+
81+
static Reducer custom(String functionName, String... args) {
82+
return new ReducerParams(functionName, args);
83+
}
84+
85+
Reducer as(String alias);
86+
87+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* Copyright (c) 2013-2024 Nikita Koksharov
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.redisson.api.search;
17+
18+
import java.util.Arrays;
19+
import java.util.List;
20+
21+
/**
22+
*
23+
* @author Nikita Koksharov
24+
*
25+
*/
26+
public final class ReducerParams implements Reducer {
27+
28+
private String as;
29+
private String functionName;
30+
private List<String> args;
31+
32+
ReducerParams(String functionName, String... args) {
33+
this.functionName = functionName;
34+
this.args = Arrays.asList(args);
35+
}
36+
37+
@Override
38+
public Reducer as(String alias) {
39+
this.as = alias;
40+
return this;
41+
}
42+
43+
public String getAs() {
44+
return as;
45+
}
46+
47+
public String getFunctionName() {
48+
return functionName;
49+
}
50+
51+
public List<String> getArgs() {
52+
return args;
53+
}
54+
}

redisson/src/main/java/org/redisson/api/search/query/hybrid/HybridQueryArgs.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
*/
1616
package org.redisson.api.search.query.hybrid;
1717

18-
import org.redisson.api.search.aggregate.Expression;
19-
import org.redisson.api.search.aggregate.GroupBy;
18+
import org.redisson.api.search.Expression;
19+
import org.redisson.api.search.GroupBy;
2020

2121
import java.time.Duration;
2222

redisson/src/main/java/org/redisson/api/search/query/hybrid/HybridQueryParams.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
package org.redisson.api.search.query.hybrid;
1717

1818
import org.redisson.api.SortOrder;
19-
import org.redisson.api.search.aggregate.Expression;
20-
import org.redisson.api.search.aggregate.GroupBy;
19+
import org.redisson.api.search.Expression;
20+
import org.redisson.api.search.GroupBy;
2121

2222
import java.time.Duration;
2323
import java.util.*;

redisson/src/test/java/org/redisson/RedissonSearchTest.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,9 +1128,9 @@ public void testHybridSearchWithGroupBy() {
11281128
.vectorSimilarity(VectorSimilarity.of("@vec", "$vec")
11291129
.nearestNeighbors(10))
11301130
.params(Map.of("vec", queryVector))
1131-
.groupBy(GroupBy.fieldNames("@category")
1132-
.reducers(Reducer.count().as("count"),
1133-
Reducer.avg("@price").as("avg_price")))
1131+
.groupBy(org.redisson.api.search.GroupBy.fieldNames("@category")
1132+
.reducers(org.redisson.api.search.Reducer.count().as("count"),
1133+
org.redisson.api.search.Reducer.avg("@price").as("avg_price")))
11341134
.limit(0, 10));
11351135

11361136
assertThat(result.getResults()).containsExactlyInAnyOrder(
@@ -1173,7 +1173,7 @@ public void testHybridSearchWithApply() {
11731173
.nearestNeighbors(5))
11741174
.params(Map.of("vec", queryVector))
11751175
.load("@price")
1176-
.apply(new Expression("@price * 0.9", "discounted_price"))
1176+
.apply(new org.redisson.api.search.Expression("@price * 0.9", "discounted_price"))
11771177
.limit(0, 5));
11781178

11791179
assertThat(result.getResults()).containsExactlyInAnyOrder(
@@ -1402,7 +1402,7 @@ public void testHybridSearchFullOptions() {
14021402
.window(30)
14031403
.constant(60))
14041404
.load("@title", "@price", "@rating", "@category")
1405-
.apply(new Expression("@price * 0.85", "sale_price"))
1405+
.apply(new org.redisson.api.search.Expression("@price * 0.85", "sale_price"))
14061406
.timeout(Duration.ofSeconds(10))
14071407
.limit(0, 5));
14081408

0 commit comments

Comments
 (0)