diff --git a/Examples/AdvancedJsonExamples.md b/Examples/AdvancedJsonExamples.md
index 53ac2f72..aa597d74 100644
--- a/Examples/AdvancedJsonExamples.md
+++ b/Examples/AdvancedJsonExamples.md
@@ -50,7 +50,7 @@ The ability to query within a JSON object unlocks further value to the underlyin
```
## Data Loading
```c#
-IJsonCommands json = db.JSON();
+JsonCommands json = db.JSON();
json.Set("warehouse:1", "$", new {
city = "Boston",
location = "42.361145, -71.057083",
diff --git a/Examples/AdvancedQueryOperations.md b/Examples/AdvancedQueryOperations.md
index 7f2fd88c..4573e60c 100644
--- a/Examples/AdvancedQueryOperations.md
+++ b/Examples/AdvancedQueryOperations.md
@@ -7,7 +7,7 @@ Aggregation and other more complex RediSearch queries
1. [Data Load](#vss_dataload)
2. [Index Creation](#vss_index)
3. [Search](#vss_search)
- 4. [Hybrid query Search](#vss_hybrid_query_search)
+ 4. [Hybrid Query Search](#vss_hybrid_query_search)
4. [Advanced Search Queries](#adv_search)
1. [Data Set](#advs_dataset)
2. [Data Load](#advs_dataload)
@@ -66,7 +66,7 @@ db.HashSet("vec:4", new HashEntry[]
### Index Creation
#### Command
```c#
-ISearchCommands ft = db.FT();
+SearchCommands ft = db.FT();
try {ft.DropIndex("vss_idx");} catch {};
Console.WriteLine(ft.Create("vss_idx", new FTCreateParams().On(IndexDataType.HASH).Prefix("vec:"),
new Schema()
@@ -193,7 +193,7 @@ vec:3 is not returned because it has tag B
### Data Load
```c#
-IJsonCommands json = db.JSON();
+JsonCommands json = db.JSON();
json.Set("warehouse:1", "$", new {
city = "Boston",
location = "-71.057083, 42.361145",
@@ -253,7 +253,7 @@ json.Set("warehouse:2", "$", new {
### Index Creation
#### Command
```c#
-ISearchCommands ft = db.FT();
+SearchCommands ft = db.FT();
try {ft.DropIndex("wh_idx");} catch {};
Console.WriteLine(ft.Create("wh_idx", new FTCreateParams()
.On(IndexDataType.JSON)
diff --git a/Examples/BasicJsonExamples.md b/Examples/BasicJsonExamples.md
index f64d924a..bebb2c90 100644
--- a/Examples/BasicJsonExamples.md
+++ b/Examples/BasicJsonExamples.md
@@ -38,7 +38,7 @@ Document stores are a NoSQL database type that provide flexible schemas and acce
Insert a simple KVP as a JSON object.
#### Command
```c#
-IJsonCommands json = db.JSON();
+JsonCommands json = db.JSON();
Console.WriteLine(json.Set("ex1:1", "$", "\"val\""));
```
#### Result
diff --git a/Examples/BasicQueryOperations.md b/Examples/BasicQueryOperations.md
index dac955e6..11e11ac6 100644
--- a/Examples/BasicQueryOperations.md
+++ b/Examples/BasicQueryOperations.md
@@ -65,7 +65,7 @@ using NRedisStack.Search.Literals.Enums;
```
## Data Loading
```c#
-IJsonCommands json = db.JSON();
+JsonCommands json = db.JSON();
json.Set("product:15970", "$", new {
id = 15970,
gender = "Men",
@@ -100,7 +100,7 @@ json.Set("product:46885", "$", new {
#### Command
```c#
-ISearchCommands ft = db.FT();
+SearchCommands ft = db.FT();
try {ft.DropIndex("idx1");} catch {};
ft.Create("idx1", new FTCreateParams().On(IndexDataType.JSON)
.Prefix("product:"),
diff --git a/README.md b/README.md
index a67c008c..4df53d5c 100644
--- a/README.md
+++ b/README.md
@@ -60,15 +60,15 @@ IDatabase db = redis.GetDatabase();
```
Now you can create a variable from any type of module in the following way:
```csharp
-IBloomCommands bf = db.BF();
-ICuckooCommands cf = db.CF();
-ICmsCommands cms = db.CMS();
-IGraphCommands graph = db.GRAPH();
-ITopKCommands topk = db.TOPK();
-ITdigestCommands tdigest = db.TDIGEST();
-ISearchCommands ft = db.FT();
-IJsonCommands json = db.JSON();
-ITimeSeriesCommands ts = db.TS();
+BloomCommands bf = db.BF();
+CuckooCommands cf = db.CF();
+CmsCommands cms = db.CMS();
+GraphCommands graph = db.GRAPH();
+TopKCommands topk = db.TOPK();
+TdigestCommands tdigest = db.TDIGEST();
+SearchCommands ft = db.FT();
+JsonCommands json = db.JSON();
+TimeSeriesCommands ts = db.TS();
```
Then, that variable will allow you to call all the commands of that module.
@@ -82,7 +82,7 @@ To store a json object in Redis:
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost");
IDatabase db = redis.GetDatabase();
-IJsonCommands json = db.JSON();
+JsonCommands json = db.JSON();
var key = "myKey";
json.Set(key, "$", new { Age = 35, Name = "Alice" });
```
@@ -99,8 +99,8 @@ using NRedisStack.Search.Literals.Enums;
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost");
IDatabase db = redis.GetDatabase();
-ISearchCommands ft = db.FT();
-IJsonCommands json = db.JSON();
+SearchCommands ft = db.FT();
+JsonCommands json = db.JSON();
```
Create an index with fields and weights:
diff --git a/src/NRedisStack/Pipeline.cs b/src/NRedisStack/Pipeline.cs
index bf0fa594..182a73c2 100644
--- a/src/NRedisStack/Pipeline.cs
+++ b/src/NRedisStack/Pipeline.cs
@@ -14,15 +14,15 @@ public Pipeline(IDatabase db)
public void Execute() => _batch.Execute();
- public IBloomCommandsAsync Bf => new BloomCommandsAsync(_batch);
- public ICmsCommandsAsync Cms => new CmsCommandsAsync(_batch);
- public ICuckooCommandsAsync Cf => new CuckooCommandsAsync(_batch);
- public IGraphCommandsAsync Graph => new GraphCommandsAsync(_batch);
- public IJsonCommandsAsync Json => new JsonCommandsAsync(_batch);
- public ISearchCommandsAsync Ft => new SearchCommandsAsync(_batch);
- public ITdigestCommandsAsync Tdigest => new TdigestCommandsAsync(_batch);
- public ITimeSeriesCommandsAsync Ts => new TimeSeriesCommandsAsync(_batch);
- public ITopKCommandsAsync TopK => new TopKCommandsAsync(_batch);
+ public BloomCommandsAsync Bf => new BloomCommandsAsync(_batch);
+ public CmsCommandsAsync Cms => new CmsCommandsAsync(_batch);
+ public CuckooCommandsAsync Cf => new CuckooCommandsAsync(_batch);
+ public GraphCommandsAsync Graph => new GraphCommandsAsync(_batch);
+ public JsonCommandsAsync Json => new JsonCommandsAsync(_batch);
+ public SearchCommandsAsync Ft => new SearchCommandsAsync(_batch);
+ public TdigestCommandsAsync Tdigest => new TdigestCommandsAsync(_batch);
+ public TimeSeriesCommandsAsync Ts => new TimeSeriesCommandsAsync(_batch);
+ public TopKCommandsAsync TopK => new TopKCommandsAsync(_batch);
public IDatabaseAsync Db => _batch;
}
\ No newline at end of file
diff --git a/src/NRedisStack/ResponseParser.cs b/src/NRedisStack/ResponseParser.cs
index 7071476b..2865531e 100644
--- a/src/NRedisStack/ResponseParser.cs
+++ b/src/NRedisStack/ResponseParser.cs
@@ -7,6 +7,8 @@
using NRedisStack.CountMinSketch.DataTypes;
using NRedisStack.TopK.DataTypes;
using NRedisStack.Tdigest.DataTypes;
+using NRedisStack.Search;
+using NRedisStack.Search.Aggregation;
namespace NRedisStack
{
@@ -614,6 +616,92 @@ public static IEnumerable> ToHashSets(this RedisResult result)
return sets;
}
+ public static Dictionary> ToFtSpellCheckResult(this RedisResult result)
+ {
+ var rawTerms = (RedisResult[])result!;
+ var returnTerms = new Dictionary>(rawTerms.Length);
+ foreach (var term in rawTerms)
+ {
+ var rawElements = (RedisResult[])term!;
+
+ string termValue = rawElements[1].ToString()!;
+
+ var list = (RedisResult[]) rawElements[2]!;
+ Dictionary entries = new Dictionary(list.Length);
+ foreach (var entry in list)
+ {
+ var entryElements = (RedisResult[])entry!;
+ string suggestion = entryElements[1].ToString()!;
+ double score = (double)entryElements[0];
+ entries.Add(suggestion, score);
+ }
+ returnTerms.Add(termValue, entries);
+ }
+
+ return returnTerms;
+ }
+
+ public static List> ToStringDoubleTupleList(this RedisResult result) // TODO: consider create class Suggestion instead of List>
+ {
+ var results = (RedisResult[])result!;
+ var list = new List>(results.Length / 2);
+ for (int i = 0; i < results.Length; i += 2)
+ {
+ var suggestion = results[i].ToString()!;
+ var score = (double)results[i + 1];
+ list.Add(new Tuple(suggestion, score));
+ }
+ return list;
+ }
+
+ public static Dictionary ToStringRedisResultDictionary(this RedisResult value)
+ {
+ var res = (RedisResult[])value!;
+ var dict = new Dictionary();
+ foreach (var pair in res)
+ {
+ var arr = (RedisResult[])pair!;
+ dict.Add(arr[0].ToString(), arr[1]);
+ }
+ return dict;
+ }
+
+ public static Tuple> ToProfileSearchResult(this RedisResult result, Query q)
+ {
+ var results = (RedisResult[])result!;
+
+ var searchResult = results[0].ToSearchResult(q);
+ var profile = results[1].ToStringRedisResultDictionary();
+ return new Tuple>(searchResult, profile);
+ }
+
+ public static SearchResult ToSearchResult(this RedisResult result, Query q)
+ {
+ return new SearchResult((RedisResult[])result!, !q.NoContent, q.WithScores, q.WithPayloads/*, q.ExplainScore*/);
+ }
+
+ public static Tuple> ToProfileAggregateResult(this RedisResult result, AggregationRequest q)
+ {
+ var results = (RedisResult[])result!;
+ var aggregateResult = results[0].ToAggregationResult(q);
+ var profile = results[1].ToStringRedisResultDictionary();
+ return new Tuple>(aggregateResult, profile);
+ }
+
+ public static AggregationResult ToAggregationResult(this RedisResult result, AggregationRequest query)
+ {
+ if (query.IsWithCursor())
+ {
+ var results = (RedisResult[])result!;
+
+ return new AggregationResult(results[0], (long)results[1]);
+ }
+ else
+ {
+ return new AggregationResult(result);
+ }
+ }
+
public static Dictionary[] ToDictionarys(this RedisResult result)
{
var resArr = (RedisResult[])result!;
@@ -624,6 +712,7 @@ public static Dictionary[] ToDictionarys(this RedisResult r
}
return dicts;
+
}
}
}
\ No newline at end of file
diff --git a/src/NRedisStack/Search/FTSpellCheckParams.cs b/src/NRedisStack/Search/FTSpellCheckParams.cs
new file mode 100644
index 00000000..97242604
--- /dev/null
+++ b/src/NRedisStack/Search/FTSpellCheckParams.cs
@@ -0,0 +1,96 @@
+using NRedisStack.Search.Literals;
+namespace NRedisStack.Search
+{
+ public class FTSpellCheckParams
+ {
+ List