From 4a39b5febc8ac26fbaf84b2c34e030c19c3b5220 Mon Sep 17 00:00:00 2001 From: shacharPash Date: Sun, 5 Mar 2023 13:55:19 +0200 Subject: [PATCH 1/4] Add ToJson() in SearchResult + example & test --- Examples/ConvertSearchResultToJson.md | 31 +++++++++++++++++++ src/NRedisStack/Search/SearchResult.cs | 5 +++ .../Examples/ExamplesTests.cs | 28 +++++++++++++++-- 3 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 Examples/ConvertSearchResultToJson.md diff --git a/Examples/ConvertSearchResultToJson.md b/Examples/ConvertSearchResultToJson.md new file mode 100644 index 00000000..e0e79622 --- /dev/null +++ b/Examples/ConvertSearchResultToJson.md @@ -0,0 +1,31 @@ +# Converting Search Result to JSON +## This example shows how to convert Redis search results to JSON format using NRedisStack. + +Connect to the Redis server: +```csharp +var redis = ConnectionMultiplexer.Connect("localhost"); +``` +Get a reference to the database and for search and json commands: +```csharp +var db = redis.GetDatabase(); +var ft = db.FT(); +var json = db.JSON(); +``` +Create a search index with a JSON field: +```csharp +ft.Create("test", new FTCreateParams().On(IndexDataType.JSON).Prefix("doc:"), + new Schema().AddTagField(new FieldName("$.name", "name"))); +``` +Insert 10 JSON documents into the index +```csharp +for (int i = 0; i < 10; i++) +{ + json.Set("doc:" + i, "$", "{\"name\":\"foo\"}"); +} +``` +Execute a search query and convert the results to JSON +```csharp +var res = ft.Search("test", new Query("@name:{foo}")); +var docs = res.ToJson(); +``` +Now the `docs` variable contains a JSON list (IEnumerable) of the search results. \ No newline at end of file diff --git a/src/NRedisStack/Search/SearchResult.cs b/src/NRedisStack/Search/SearchResult.cs index 4232c5c0..98a211ea 100644 --- a/src/NRedisStack/Search/SearchResult.cs +++ b/src/NRedisStack/Search/SearchResult.cs @@ -12,6 +12,11 @@ public class SearchResult public long TotalResults { get; } public List Documents { get; } + /// + /// converts the documents to a list of json strings + /// + public IEnumerable ToJson() => Documents.Select(x => x["json"]); + internal SearchResult(RedisResult[] resp, bool hasContent, bool hasScores, bool hasPayloads/*, bool shouldExplainScore*/) { // Calculate the step distance to walk over the results. diff --git a/tests/NRedisStack.Tests/Examples/ExamplesTests.cs b/tests/NRedisStack.Tests/Examples/ExamplesTests.cs index 7af5530d..c734009a 100644 --- a/tests/NRedisStack.Tests/Examples/ExamplesTests.cs +++ b/tests/NRedisStack.Tests/Examples/ExamplesTests.cs @@ -226,7 +226,7 @@ public async Task TransactionExample() var tran = new Transaction(db); // Add account details with Json.Set to transaction - tran.Json.SetAsync("accdetails:Jeeva", "$", new { name = "Jeeva", totalAmount= 1000, bankName = "City" }); + tran.Json.SetAsync("accdetails:Jeeva", "$", new { name = "Jeeva", totalAmount = 1000, bankName = "City" }); tran.Json.SetAsync("accdetails:Shachar", "$", new { name = "Shachar", totalAmount = 1000, bankName = "City" }); // Get the Json response @@ -240,8 +240,8 @@ public async Task TransactionExample() tran.Json.NumIncrbyAsync("accdetails:Shachar", "$.totalAmount", 200); // Get total amount for both Jeeva = 800 & Shachar = 1200 - var totalAmtOfJeeva = tran.Json.GetAsync("accdetails:Jeeva", path:"$.totalAmount"); - var totalAmtOfShachar = tran.Json.GetAsync("accdetails:Shachar", path:"$.totalAmount"); + var totalAmtOfJeeva = tran.Json.GetAsync("accdetails:Jeeva", path: "$.totalAmount"); + var totalAmtOfShachar = tran.Json.GetAsync("accdetails:Shachar", path: "$.totalAmount"); // Execute the transaction var condition = tran.ExecuteAsync(); @@ -253,4 +253,26 @@ public async Task TransactionExample() Assert.Equal("[800]", totalAmtOfJeeva.Result.ToString()); Assert.Equal("[1200]", totalAmtOfShachar.Result.ToString()); } + + [Fact] + public void TestJsonConvert() + { + ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost"); + IDatabase db = redis.GetDatabase(); + db.Execute("FLUSHALL"); + ISearchCommands ft = db.FT(); + IJsonCommands json = db.JSON(); + + ft.Create("test", new FTCreateParams().On(IndexDataType.JSON).Prefix("doc:"), + new Schema().AddTagField(new FieldName("$.name", "name"))); + for (int i = 0; i < 10; i++) + { + json.Set("doc:" + i, "$", "{\"name\":\"foo\"}"); + } + var res = ft.Search("test", new Query("@name:{foo}")); + + var docs = res.ToJson(); + + Assert.Equal(10, docs.Count()); + } } \ No newline at end of file From ef2e98b1c5724c65fc025a64d1c2ccb2f1d59cb3 Mon Sep 17 00:00:00 2001 From: shacharPash Date: Sun, 5 Mar 2023 14:56:32 +0200 Subject: [PATCH 2/4] add Where not null --- src/NRedisStack/Search/SearchResult.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/NRedisStack/Search/SearchResult.cs b/src/NRedisStack/Search/SearchResult.cs index 98a211ea..5abbc2e0 100644 --- a/src/NRedisStack/Search/SearchResult.cs +++ b/src/NRedisStack/Search/SearchResult.cs @@ -15,7 +15,8 @@ public class SearchResult /// /// converts the documents to a list of json strings /// - public IEnumerable ToJson() => Documents.Select(x => x["json"]); + public IEnumerable? ToJson() => Documents.Select(x => x["json"].ToString()) + .Where(x => !string.IsNullOrEmpty(x)); internal SearchResult(RedisResult[] resp, bool hasContent, bool hasScores, bool hasPayloads/*, bool shouldExplainScore*/) { From 337390139d8f62146739478bc826fbe007c6b535 Mon Sep 17 00:00:00 2001 From: shacharPash Date: Sun, 5 Mar 2023 15:06:07 +0200 Subject: [PATCH 3/4] add assertion --- tests/NRedisStack.Tests/Examples/ExamplesTests.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/NRedisStack.Tests/Examples/ExamplesTests.cs b/tests/NRedisStack.Tests/Examples/ExamplesTests.cs index c734009a..5ee2b46a 100644 --- a/tests/NRedisStack.Tests/Examples/ExamplesTests.cs +++ b/tests/NRedisStack.Tests/Examples/ExamplesTests.cs @@ -61,6 +61,10 @@ public void HSETandSearch() // Search for hashes with last name of Rod var lastNameRod = ft.Search("example_index", new Query("@last:Rod")); // lastNameRod is empty because there are no hashes with a last name of Rod that match the index definition + Assert.Equal(4, noFilters.TotalResults); + Assert.Equal(2, startWithJo.TotalResults); + Assert.Equal(1, namedPat.TotalResults); + Assert.Equal(0, lastNameRod.TotalResults); } [Fact] From 0c514bc158d472b19ed84ad40c374e5e5298b337 Mon Sep 17 00:00:00 2001 From: shacharPash Date: Sun, 5 Mar 2023 16:14:55 +0200 Subject: [PATCH 4/4] fixes --- Examples/ConvertSearchResultToJson.md | 4 ++-- src/NRedisStack/Search/SearchResult.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Examples/ConvertSearchResultToJson.md b/Examples/ConvertSearchResultToJson.md index e0e79622..2d060e39 100644 --- a/Examples/ConvertSearchResultToJson.md +++ b/Examples/ConvertSearchResultToJson.md @@ -16,14 +16,14 @@ Create a search index with a JSON field: ft.Create("test", new FTCreateParams().On(IndexDataType.JSON).Prefix("doc:"), new Schema().AddTagField(new FieldName("$.name", "name"))); ``` -Insert 10 JSON documents into the index +Insert 10 JSON documents into the index: ```csharp for (int i = 0; i < 10; i++) { json.Set("doc:" + i, "$", "{\"name\":\"foo\"}"); } ``` -Execute a search query and convert the results to JSON +Execute a search query and convert the results to JSON: ```csharp var res = ft.Search("test", new Query("@name:{foo}")); var docs = res.ToJson(); diff --git a/src/NRedisStack/Search/SearchResult.cs b/src/NRedisStack/Search/SearchResult.cs index 5abbc2e0..76a76cfb 100644 --- a/src/NRedisStack/Search/SearchResult.cs +++ b/src/NRedisStack/Search/SearchResult.cs @@ -13,7 +13,7 @@ public class SearchResult public List Documents { get; } /// - /// converts the documents to a list of json strings + /// Converts the documents to a list of json strings. only works on a json documents index. /// public IEnumerable? ToJson() => Documents.Select(x => x["json"].ToString()) .Where(x => !string.IsNullOrEmpty(x));