Skip to content

Commit

Permalink
Support Search commands after RESP3 update (#3464)
Browse files Browse the repository at this point in the history
* Ignore PROFILE LIMITED test due to crash

* FT._LIST returns Set

* a commit for CONFIG GET

* a commit for SPELLCHECK

* Search search works

* Search aggregation

* Ignore pending server update tests

* doc breaking changes

* fix

* ignore ftSearch binary test

* breaking doc

* comment

* FT.PROFILE

* assert info

* more asserts and edits

* FT.SPELLCHECK RESP3 current implementation

* 'extra_attributes' as map key for results

* Address FT.SPELLCHECK changes

* FT.INFO in RESP3 test

* FT.PROFILE SEARCH MAXPREFIXEXPANSIONS test

* FT.PROFILE SEARCH NOCONTENT test

* FT.PROFILE SEARCH with deep reply test

* FT.PROFILE SEARCH LIMITED test

* Bring back RESP2 tests for last few commits

* Remove imports

* Remove imports

* Fix FT.PROFILE SEARCH NOCONTENT in RESP2 test

* Use protocol variable in SearchWithParamsTest
  • Loading branch information
sazzad16 authored Aug 16, 2023
1 parent 5792218 commit 9a71576
Show file tree
Hide file tree
Showing 21 changed files with 697 additions and 248 deletions.
8 changes: 8 additions & 0 deletions docs/jedis5-breaking.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@

- `getAgeSeconds()` in `AccessControlLogEntry` now returns `Double` instead of `String`.

- Both `ftConfigGet(String option)` and `ftConfigGet(String indexName, String option)` methods now return `Map<String, Object>` instead of `Map<String, String>`.

- `ftList()` method now returns `Set<String>` instead of `List<String>`.

- `graphSlowlog(String graphName)` now returns `List<List<Object>>` (instead of `List<List<String>>`).

- All _payload_ related parameters are removed from _search_ related classes; namely `Document`, `IndexDefinition`, `Query`.
Expand Down Expand Up @@ -74,6 +78,10 @@

- `getParams()` method is removed from `SortingParams` class.

- Both `SEARCH_AGGREGATION_RESULT` and `SEARCH_AGGREGATION_RESULT_WITH_CURSOR` implementations from `SearchBuilderFactory` class have been moved to `AggregationResult` class.

- All `AggregationResult` constructors have been made `private`.

- `addCommandEncodedArguments` and `addCommandBinaryArguments` methods have been removed from `FieldName` class.

- `getArgs` method is removed from `AggregationBuilder` class.
Expand Down
116 changes: 92 additions & 24 deletions src/main/java/redis/clients/jedis/BuilderFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -290,91 +290,122 @@ public String toString() {
}
};

public static final Builder<Map<String, Object>> ENCODED_OBJECT_MAP = new Builder<Map<String, Object>>() {
public static final Builder<Map<byte[], byte[]>> BINARY_MAP = new Builder<Map<byte[], byte[]>>() {
@Override
public Map<String, Object> build(Object data) {
if (data == null) return null;
@SuppressWarnings("unchecked")
public Map<byte[], byte[]> build(Object data) {
final List<Object> list = (List<Object>) data;
if (list.isEmpty()) return Collections.emptyMap();

if (list.get(0) instanceof KeyValue) {
final Map<String, Object> map = new HashMap<>(list.size(), 1f);
final Map<byte[], byte[]> map = new JedisByteHashMap();
final Iterator iterator = list.iterator();
while (iterator.hasNext()) {
KeyValue kv = (KeyValue) iterator.next();
map.put(STRING.build(kv.getKey()), ENCODED_OBJECT.build(kv.getValue()));
map.put(BINARY.build(kv.getKey()), BINARY.build(kv.getValue()));
}
return map;
} else {
final Map<String, Object> map = new HashMap<>(list.size() / 2, 1f);
final Map<byte[], byte[]> map = new JedisByteHashMap();
final Iterator iterator = list.iterator();
while (iterator.hasNext()) {
map.put(STRING.build(iterator.next()), ENCODED_OBJECT.build(iterator.next()));
map.put(BINARY.build(iterator.next()), BINARY.build(iterator.next()));
}
return map;
}
}

@Override
public String toString() {
return "Map<byte[], byte[]>";
}
};

public static final Builder<Map<byte[], byte[]>> BINARY_MAP = new Builder<Map<byte[], byte[]>>() {
public static final Builder<Map<String, String>> STRING_MAP = new Builder<Map<String, String>>() {
@Override
@SuppressWarnings("unchecked")
public Map<byte[], byte[]> build(Object data) {
public Map<String, String> build(Object data) {
final List<Object> list = (List<Object>) data;
if (list.isEmpty()) return Collections.emptyMap();

if (list.get(0) instanceof KeyValue) {
final Map<byte[], byte[]> map = new JedisByteHashMap();
final Map<String, String> map = new HashMap<>(list.size(), 1f);
final Iterator iterator = list.iterator();
while (iterator.hasNext()) {
KeyValue kv = (KeyValue) iterator.next();
map.put(BINARY.build(kv.getKey()), BINARY.build(kv.getValue()));
map.put(STRING.build(kv.getKey()), STRING.build(kv.getValue()));
}
return map;
} else {
final Map<byte[], byte[]> map = new JedisByteHashMap();
final Map<String, String> map = new HashMap<>(list.size() / 2, 1f);
final Iterator iterator = list.iterator();
while (iterator.hasNext()) {
map.put(BINARY.build(iterator.next()), BINARY.build(iterator.next()));
map.put(STRING.build(iterator.next()), STRING.build(iterator.next()));
}
return map;
}
}

@Override
public String toString() {
return "Map<byte[], byte[]>";
return "Map<String, String>";
}
};

public static final Builder<Map<String, String>> STRING_MAP = new Builder<Map<String, String>>() {
public static final Builder<Map<String, Object>> ENCODED_OBJECT_MAP = new Builder<Map<String, Object>>() {
@Override
@SuppressWarnings("unchecked")
public Map<String, String> build(Object data) {
public Map<String, Object> build(Object data) {
if (data == null) return null;
final List<Object> list = (List<Object>) data;
if (list.isEmpty()) return Collections.emptyMap();

if (list.get(0) instanceof KeyValue) {
final Map<String, String> map = new HashMap<>(list.size(), 1f);
final Map<String, Object> map = new HashMap<>(list.size(), 1f);
final Iterator iterator = list.iterator();
while (iterator.hasNext()) {
KeyValue kv = (KeyValue) iterator.next();
map.put(STRING.build(kv.getKey()), STRING.build(kv.getValue()));
map.put(STRING.build(kv.getKey()), ENCODED_OBJECT.build(kv.getValue()));
}
return map;
} else {
final Map<String, String> map = new HashMap<>(list.size() / 2, 1f);
final Map<String, Object> map = new HashMap<>(list.size() / 2, 1f);
final Iterator iterator = list.iterator();
while (iterator.hasNext()) {
map.put(STRING.build(iterator.next()), STRING.build(iterator.next()));
map.put(STRING.build(iterator.next()), ENCODED_OBJECT.build(iterator.next()));
}
return map;
}
}
};

public static final Builder<Object> AGGRESSIVE_ENCODED_OBJECT = new Builder<Object>() {
@Override
public String toString() {
return "Map<String, String>";
public Object build(Object data) {
if (data == null) return null;

if (data instanceof List) {
final List list = (List) data;
if (list.isEmpty()) return Collections.emptyMap();

if (list.get(0) instanceof KeyValue) {
return ((List<KeyValue>) data).stream()
.filter(kv -> kv != null && kv.getKey() != null && kv.getValue() != null)
.collect(Collectors.toMap(kv -> STRING.build(kv.getKey()),
kv -> this.build(kv.getValue())));
} else {
return list.stream().map(this::build).collect(Collectors.toList());
}
} else if (data instanceof byte[]) {
return STRING.build(data);
}
return data;
}
};

public static final Builder<Map<String, Object>> AGGRESSIVE_ENCODED_OBJECT_MAP = new Builder<Map<String, Object>>() {
@Override
public Map<String, Object> build(Object data) {
return (Map<String, Object>) AGGRESSIVE_ENCODED_OBJECT.build(data);
}
};

Expand Down Expand Up @@ -1736,7 +1767,15 @@ private void addMatchedPosition(List<MatchedPosition> matchedPositions, Object o
@Override
@SuppressWarnings("unchecked")
public Map<String, String> build(Object data) {
final List<Object> list = (List<Object>) data;
final List list = (List) data;
if (list.isEmpty()) return Collections.emptyMap();

if (list.get(0) instanceof KeyValue) {
return ((List<KeyValue>) list).stream()
.collect(Collectors.toMap(kv -> STRING.build(kv.getKey()),
kv -> STRING.build(kv.getValue())));
}

final Map<String, String> map = new HashMap<>(list.size());
for (Object object : list) {
if (object == null) continue;
Expand All @@ -1753,6 +1792,35 @@ public String toString() {
}
};

public static final Builder<Map<String, Object>> ENCODED_OBJECT_MAP_FROM_PAIRS = new Builder<Map<String, Object>>() {
@Override
@SuppressWarnings("unchecked")
public Map<String, Object> build(Object data) {
final List list = (List) data;
if (list.isEmpty()) return Collections.emptyMap();

if (list.get(0) instanceof KeyValue) {
return ((List<KeyValue>) list).stream()
.collect(Collectors.toMap(kv -> STRING.build(kv.getKey()),
kv -> ENCODED_OBJECT.build(kv.getValue())));
}

final Map<String, Object> map = new HashMap<>(list.size());
for (Object object : list) {
if (object == null) continue;
final List<Object> flat = (List<Object>) object;
if (flat.isEmpty()) continue;
map.put(STRING.build(flat.get(0)), STRING.build(flat.get(1)));
}
return map;
}

@Override
public String toString() {
return "Map<String, String>";
}
};

public static final Builder<List<LibraryInfo>> LIBRARY_LIST = new Builder<List<LibraryInfo>>() {
@Override
public List<LibraryInfo> build(Object data) {
Expand Down
Loading

0 comments on commit 9a71576

Please sign in to comment.