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 1e5adc0..1d01c77 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 @@ -606,12 +606,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 48a84ea..b24785c 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 @@ -47,7 +47,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 c95aac3..1a3c583 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 @@ -31,23 +31,50 @@ */ 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); - } + private boolean withScores; + + public SearchResultDecoder() { + } + + public SearchResultDecoder(boolean withScores) { + this.withScores = withScores; + } + + @Override + public Decoder getDecoder(int paramNum, State state) { + return null; + } + + @Override + public SearchResult decode(List parts, State state) { + Long total = (Long) parts.get(0); + int documentSize = withScores ? 3 : 2; + boolean noContent = total == parts.size() + 1; + + 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 { + //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); + } } 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 f5be27f..0909b29 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 @@ -157,7 +157,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); }