From 1561568cb7d642817930761a06104e32cb44f4f3 Mon Sep 17 00:00:00 2001 From: "regis.oliveira" Date: Sun, 18 Apr 2021 00:46:26 -0300 Subject: [PATCH 1/2] Supports Scores Search Parameter --- .../protocol/decoder/SearchResultDecoder.java | 74 ++++++++++++++----- 1 file changed, 54 insertions(+), 20 deletions(-) diff --git a/redisearch/src/main/java/io/github/dengliming/redismodule/redisearch/protocol/decoder/SearchResultDecoder.java b/redisearch/src/main/java/io/github/dengliming/redismodule/redisearch/protocol/decoder/SearchResultDecoder.java index 7094725..916a0e4 100644 --- a/redisearch/src/main/java/io/github/dengliming/redismodule/redisearch/protocol/decoder/SearchResultDecoder.java +++ b/redisearch/src/main/java/io/github/dengliming/redismodule/redisearch/protocol/decoder/SearchResultDecoder.java @@ -22,6 +22,7 @@ import org.redisson.client.protocol.decoder.MultiDecoder; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -30,24 +31,57 @@ */ public class SearchResultDecoder implements MultiDecoder { - @Override - public Decoder getDecoder(int paramNum, State state) { - return null; - } - - @Override - public SearchResult decode(List parts, State state) { - Long total = (Long) parts.get(0); - boolean noContent = total.longValue() == parts.size() + 1; - List documents = new ArrayList<>(total.intValue()); - for (int i = 1; i < parts.size(); i++) { - if (noContent) { - documents.add(new Document((String) parts.get(i), 1.0d, null)); - } - else if ((i + 1) % 2 != 0) { - documents.add(new Document((String) parts.get(i - 1), 1.0d, (Map) parts.get(i))); - } - } - return new SearchResult(total, documents); - } + @Override + public Decoder getDecoder(int paramNum, State state) { + return null; + } + + @Override + public SearchResult decode(List parts, State state) { + + int documentSize = 0; + Long total = (Long) parts.get(0); + boolean noContent = total == parts.size() + 1; + + // Calculates Document Size searching for the first LinkedHashMap on parts... + // It would be better if I could access the commands parameters to check if we are dealing with the Score values... + if (!noContent && total > 0) { + do { + documentSize++; + } while (parts.get(documentSize).getClass() != LinkedHashMap.class); + } + + List documents = new ArrayList<>(total.intValue()); + + // Checks the document size. DocumentSize equals to 2 means only key and parts. DocumentSize equals to 3 means + // key, score and parts. Created separated IFs to avoid checking this logic each document. Also changed the + // step size to reduce numbers of interactions + if (documentSize == 2) { + + //Only key and parts + for (int i = 1; i < parts.size(); i += documentSize) { + if (noContent) { + documents.add(new Document((String) parts.get(i), 1.0d, null)); + } else { + documents.add(new Document((String) parts.get(i), 1.0d, (Map) parts.get(i + 1))); + } + } + + } else if (documentSize == 3) { + + //Key, score and parts + for (int i = 1; i < parts.size(); i += documentSize) { + if (noContent) { + documents.add(new Document((String) parts.get(i), (Double) parts.get(i + 1), null)); + } else { + documents.add(new Document((String) parts.get(i), Double.parseDouble((String) parts.get(i + 1)), (Map) parts.get(i + 2))); + } + } + + } + + return new SearchResult(total, documents); + + } + } From 77b82b0b1108f8032f2876eb0e47fb601f9cbe23 Mon Sep 17 00:00:00 2001 From: "regis.oliveira" Date: Sun, 18 Apr 2021 09:22:00 -0300 Subject: [PATCH 2/2] Command FT_SEARCH_WITH_SCORES --- .../redismodule/redisearch/RediSearch.java | 17 +++++++++----- .../redisearch/protocol/RedisCommands.java | 2 ++ .../protocol/decoder/SearchResultDecoder.java | 23 ++++++++++--------- .../redisearch/search/SearchOptions.java | 6 ++++- 4 files changed, 30 insertions(+), 18 deletions(-) diff --git a/redisearch/src/main/java/io/github/dengliming/redismodule/redisearch/RediSearch.java b/redisearch/src/main/java/io/github/dengliming/redismodule/redisearch/RediSearch.java index eb9b0e5..4233757 100644 --- a/redisearch/src/main/java/io/github/dengliming/redismodule/redisearch/RediSearch.java +++ b/redisearch/src/main/java/io/github/dengliming/redismodule/redisearch/RediSearch.java @@ -568,12 +568,17 @@ public RFuture searchAsync(String query, SearchOptions searchOptio checkQueryArgument(query); RAssert.notNull(searchOptions, "SearchOptions must be not null"); - List args = new ArrayList<>(); - args.add(getName()); - args.add(query); - searchOptions.build(args); - return commandExecutor.readAsync(getName(), StringCodec.INSTANCE, FT_SEARCH, args.toArray()); - } + List args = new ArrayList<>(); + args.add(getName()); + args.add(query); + searchOptions.build(args); + return commandExecutor.readAsync( + getName(), + StringCodec.INSTANCE, + searchOptions.isWithScores() ? FT_SEARCH_WITH_SCORES : FT_SEARCH, + args.toArray() + ); + } /** * Runs a search query on an index, and performs aggregate transformations on the results. diff --git a/redisearch/src/main/java/io/github/dengliming/redismodule/redisearch/protocol/RedisCommands.java b/redisearch/src/main/java/io/github/dengliming/redismodule/redisearch/protocol/RedisCommands.java index 69593b0..d22df7e 100644 --- a/redisearch/src/main/java/io/github/dengliming/redismodule/redisearch/protocol/RedisCommands.java +++ b/redisearch/src/main/java/io/github/dengliming/redismodule/redisearch/protocol/RedisCommands.java @@ -38,7 +38,9 @@ public interface RedisCommands { RedisCommand FT_INFO = new RedisCommand<>("FT.INFO", new ListMultiDecoder2(new StringMapInfoDecoder(), new CodecDecoder(), new CodecDecoder())); RedisCommand FT_SEARCH = new RedisCommand<>("FT.SEARCH", new ListMultiDecoder2(new SearchResultDecoder(), new StringMapInfoDecoder())); + RedisCommand FT_SEARCH_WITH_SCORES = new RedisCommand<>("FT.SEARCH", new ListMultiDecoder2(new SearchResultDecoder(true), new StringMapInfoDecoder())); RedisCommand FT_AGGREGATE = new RedisCommand<>("FT.AGGREGATE", new ListMultiDecoder2(new AggregateDecoder(), new ObjectMapReplayDecoder())); + RedisCommand FT_EXPLAIN = new RedisCommand<>("FT.EXPLAIN"); RedisCommand FT_EXPLAINCLI = new RedisCommand<>("FT.EXPLAINCLI"); RedisCommand FT_DEL = new RedisCommand<>("FT.DEL", new BooleanReplayConvertor()); diff --git a/redisearch/src/main/java/io/github/dengliming/redismodule/redisearch/protocol/decoder/SearchResultDecoder.java b/redisearch/src/main/java/io/github/dengliming/redismodule/redisearch/protocol/decoder/SearchResultDecoder.java index 916a0e4..155c8c6 100644 --- a/redisearch/src/main/java/io/github/dengliming/redismodule/redisearch/protocol/decoder/SearchResultDecoder.java +++ b/redisearch/src/main/java/io/github/dengliming/redismodule/redisearch/protocol/decoder/SearchResultDecoder.java @@ -22,7 +22,6 @@ import org.redisson.client.protocol.decoder.MultiDecoder; import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -31,6 +30,16 @@ */ public class SearchResultDecoder implements MultiDecoder { + private final boolean withScores; + + public SearchResultDecoder() { + withScores = false; + } + + public SearchResultDecoder(boolean b) { + withScores = b; + } + @Override public Decoder getDecoder(int paramNum, State state) { return null; @@ -39,18 +48,10 @@ public Decoder getDecoder(int paramNum, State state) { @Override public SearchResult decode(List parts, State state) { - int documentSize = 0; Long total = (Long) parts.get(0); + int documentSize = withScores ? 3 : 2; boolean noContent = total == parts.size() + 1; - // Calculates Document Size searching for the first LinkedHashMap on parts... - // It would be better if I could access the commands parameters to check if we are dealing with the Score values... - if (!noContent && total > 0) { - do { - documentSize++; - } while (parts.get(documentSize).getClass() != LinkedHashMap.class); - } - List documents = new ArrayList<>(total.intValue()); // Checks the document size. DocumentSize equals to 2 means only key and parts. DocumentSize equals to 3 means @@ -67,7 +68,7 @@ public SearchResult decode(List parts, State state) { } } - } else if (documentSize == 3) { + } else { //Key, score and parts for (int i = 1; i < parts.size(); i += documentSize) { diff --git a/redisearch/src/main/java/io/github/dengliming/redismodule/redisearch/search/SearchOptions.java b/redisearch/src/main/java/io/github/dengliming/redismodule/redisearch/search/SearchOptions.java index 1b84216..e6960fe 100644 --- a/redisearch/src/main/java/io/github/dengliming/redismodule/redisearch/search/SearchOptions.java +++ b/redisearch/src/main/java/io/github/dengliming/redismodule/redisearch/search/SearchOptions.java @@ -156,7 +156,11 @@ public SearchOptions sort(SortBy sortBy) { return this; } - public void build(List args) { + public boolean isWithScores() { + return withScores; + } + + public void build(List args) { if (noContent) { args.add(Keywords.NOCONTENT); }