From 06c6c9cd5b7aa2342ba2661a96fdab9c2101cb6b Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Wed, 4 Jan 2023 12:01:30 +0200 Subject: [PATCH 01/27] Cover FTSearch --- .../Search/DataTypes/InfoResult.cs | 35 +++++----- .../Extensions/IndexDataTypeExtensions.cs | 13 ++-- .../Search/Literals/Enums/IndexDataType.cs | 3 +- tests/NRedisStack.Tests/Search/SearchTests.cs | 66 ++++++++++--------- 4 files changed, 61 insertions(+), 56 deletions(-) diff --git a/src/NRedisStack/Search/DataTypes/InfoResult.cs b/src/NRedisStack/Search/DataTypes/InfoResult.cs index 1040f440..298288fb 100644 --- a/src/NRedisStack/Search/DataTypes/InfoResult.cs +++ b/src/NRedisStack/Search/DataTypes/InfoResult.cs @@ -9,7 +9,7 @@ public class InfoResult public string IndexName => GetString("index_name"); public Dictionary IndexOption => GetRedisResultDictionary("index_options"); - public Dictionary IndexDefinition => GetRedisResultsDictionary("index_definition"); + // public Dictionary IndexDefinition => GetRedisResultsDictionary("index_definition"); // TODO: fix this // public Dictionary Attributes => GetRedisResultsDictionary("attributes"); // TODO: check if this is correct public Dictionary[] Attributes => GetRedisResultDictionaryArray("attributes"); // TODO: check if this is correct @@ -122,24 +122,25 @@ private Dictionary GetRedisResultDictionary(string key) } } - private Dictionary GetRedisResultsDictionary(string key) - { - if (_all.TryGetValue(key, out var value)) - { - var result = new Dictionary(); + // TODO: check if this is needed: + // private Dictionary GetRedisResultsDictionary(string key) + // { + // if (_all.TryGetValue(key, out var value)) + // { + // var result = new Dictionary(); - foreach (RedisResult[] fv in (RedisResult[])value) - { - result.Add((string)fv[0], fv); - } + // foreach (RedisResult[] fv in (RedisResult[])value) + // { + // result.Add((string)fv[0], fv); + // } - return result; - } - else - { - return default; - } - } + // return result; + // } + // else + // { + // return default; + // } + // } private Dictionary[] GetRedisResultDictionaryArray(string key) { diff --git a/src/NRedisStack/Search/Extensions/IndexDataTypeExtensions.cs b/src/NRedisStack/Search/Extensions/IndexDataTypeExtensions.cs index 13d59c3c..47392faa 100644 --- a/src/NRedisStack/Search/Extensions/IndexDataTypeExtensions.cs +++ b/src/NRedisStack/Search/Extensions/IndexDataTypeExtensions.cs @@ -12,11 +12,12 @@ internal static class IndexIndexDataType _ => throw new ArgumentOutOfRangeException(nameof(dataType), "Invalid Index DataType"), }; - public static IndexDataType AsDataType(string dataType) => dataType switch - { - "HASH" => IndexDataType.Hash, - "JSON" => IndexDataType.Json, - _ => throw new ArgumentOutOfRangeException(nameof(dataType), $"Invalid Index DataType '{dataType}'"), - }; + // TODO: needed? + // public static IndexDataType AsDataType(string dataType) => dataType switch + // { + // "HASH" => IndexDataType.Hash, + // "JSON" => IndexDataType.Json, + // _ => throw new ArgumentOutOfRangeException(nameof(dataType), $"Invalid Index DataType '{dataType}'"), + // }; } } \ No newline at end of file diff --git a/src/NRedisStack/Search/Literals/Enums/IndexDataType.cs b/src/NRedisStack/Search/Literals/Enums/IndexDataType.cs index e4b9ae34..14298ebf 100644 --- a/src/NRedisStack/Search/Literals/Enums/IndexDataType.cs +++ b/src/NRedisStack/Search/Literals/Enums/IndexDataType.cs @@ -2,7 +2,8 @@ namespace NRedisStack.Literals.Enums { public enum IndexDataType { - Json, Hash, + Json, + } } \ No newline at end of file diff --git a/tests/NRedisStack.Tests/Search/SearchTests.cs b/tests/NRedisStack.Tests/Search/SearchTests.cs index 5be01a74..bc0b2da9 100644 --- a/tests/NRedisStack.Tests/Search/SearchTests.cs +++ b/tests/NRedisStack.Tests/Search/SearchTests.cs @@ -666,6 +666,8 @@ public void AlterAdd() var info = ft.Info(index); Assert.Equal(index, info.IndexName); + Assert.Equal(0, info.IndexOption.Count); + // Assert.Equal(,info.IndexDefinition); Assert.Equal("title", (info.Attributes[0]["identifier"]).ToString()); Assert.Equal("TAG", (info.Attributes[1]["type"]).ToString()); Assert.Equal("name", (info.Attributes[2]["attribute"]).ToString()); @@ -1357,14 +1359,14 @@ public void TestFTCreateParamsCommandBuilder() .MaxTextFields() .NoOffsets() .Temporary(10) - .NoHL() + .NoHighlights() .NoFields() .NoFreqs() .Stopwords(new[] { "foo", "bar" }) .SkipInitialScan(); var builedCommand = SearchCommandBuilder.Create(index, ftCreateParams, sc); - var expectedArgs = new object[] { "TEST_INDEX", "PREFIX", 1, + var expectedArgs = new object[] { "TEST_INDEX", "ON", "JSON", "PREFIX", 1, "doc:", "FILTER", "@category:{red}", "LANGUAGE", "English", "LANGUAGE_FIELD", "play", "SCORE", 1, "SCORE_FIELD", "chapter", "PAYLOAD_FIELD", "txt", @@ -1432,7 +1434,7 @@ public void TestFilters() // Test numerical filter var q1 = new Query("foo").AddFilter(new Query.NumericFilter("num", 0, 2)); - var q2 = new Query("foo").AddFilter(new Query.NumericFilter("num",2,true, double.MaxValue, false)); + var q2 = new Query("foo").AddFilter(new Query.NumericFilter("num", 2, true, double.MaxValue, false)); q1.NoContent = q2.NoContent = true; var res1 = ft.Search("idx", q1); var res2 = ft.Search("idx", q2); @@ -1449,9 +1451,9 @@ public void TestFilters() res1 = ft.Search("idx", q1); res2 = ft.Search("idx", q2); - Assert.Equal( 1 , res1.TotalResults); - Assert.Equal( 2 , res2.TotalResults); - Assert.Equal( "doc1" , res1.Documents[0].Id); + Assert.Equal(1, res1.TotalResults); + Assert.Equal(2, res2.TotalResults); + Assert.Equal("doc1", res1.Documents[0].Id); } [Fact] @@ -1482,7 +1484,7 @@ public async Task TestFiltersAsync() // Test numerical filter var q1 = new Query("foo").AddFilter(new Query.NumericFilter("num", 0, 2)); - var q2 = new Query("foo").AddFilter(new Query.NumericFilter("num",2,true, double.MaxValue, false)); + var q2 = new Query("foo").AddFilter(new Query.NumericFilter("num", 2, true, double.MaxValue, false)); q1.NoContent = q2.NoContent = true; var res1 = await ft.SearchAsync("idx", q1); var res2 = await ft.SearchAsync("idx", q2); @@ -1499,9 +1501,9 @@ public async Task TestFiltersAsync() res1 = await ft.SearchAsync("idx", q1); res2 = await ft.SearchAsync("idx", q2); - Assert.Equal( 1 , res1.TotalResults); - Assert.Equal( 2 , res2.TotalResults); - Assert.Equal( "doc1" , res1.Documents[0].Id); + Assert.Equal(1, res1.TotalResults); + Assert.Equal(2, res2.TotalResults); + Assert.Equal("doc1", res1.Documents[0].Id); } [Fact] @@ -1515,7 +1517,7 @@ public void TestFieldsCommandBuilder() .AddTextField("txt", 1.0, true, true, true, "dm:en", true, true) .AddNumericField("num", true, true) .AddGeoField("loc", true, true) - .AddTagField("tag",true,true, true, ";", true, true) + .AddTagField("tag", true, true, true, ";", true, true) .AddVectorField("vec", VectorField.VectorAlgo.FLAT, null); var buildCommand = SearchCommandBuilder.Create("idx", new FTCreateParams(), sc); var expectedArgs = new List { @@ -1553,31 +1555,31 @@ public void TestFieldsCommandBuilder() }; Assert.Equal("FT.CREATE", buildCommand.Command); - for(int i = 0; i < expectedArgs.Count; i++) + for (int i = 0; i < expectedArgs.Count; i++) { Assert.Equal(expectedArgs[i], buildCommand.Args[i]); } } - [Fact] - public void TestModulePrefixs1() + [Fact] + public void TestModulePrefixs1() + { + { + var conn = ConnectionMultiplexer.Connect("localhost"); + IDatabase db = conn.GetDatabase(); + + var ft = db.FT(); + // ... + conn.Dispose(); + } + { - { - var conn = ConnectionMultiplexer.Connect("localhost"); - IDatabase db = conn.GetDatabase(); - - var ft = db.FT(); - // ... - conn.Dispose(); - } - - { - var conn = ConnectionMultiplexer.Connect("localhost"); - IDatabase db = conn.GetDatabase(); - - var ft = db.FT(); - // ... - conn.Dispose(); - } + var conn = ConnectionMultiplexer.Connect("localhost"); + IDatabase db = conn.GetDatabase(); + + var ft = db.FT(); + // ... + conn.Dispose(); } - } \ No newline at end of file + } +} \ No newline at end of file From d64bf36a1b9d9aae7b5a54d6fe5e09f013a17aea Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Wed, 4 Jan 2023 12:16:56 +0200 Subject: [PATCH 02/27] delete IndexIndexDataType --- .../Extensions/IndexDataTypeExtensions.cs | 23 ------------------- .../Search/FT.CREATE/FTCreateParams.cs | 2 +- .../Search/Literals/Enums/IndexDataType.cs | 4 ++-- tests/NRedisStack.Tests/Search/SearchTests.cs | 2 +- 4 files changed, 4 insertions(+), 27 deletions(-) delete mode 100644 src/NRedisStack/Search/Extensions/IndexDataTypeExtensions.cs diff --git a/src/NRedisStack/Search/Extensions/IndexDataTypeExtensions.cs b/src/NRedisStack/Search/Extensions/IndexDataTypeExtensions.cs deleted file mode 100644 index 47392faa..00000000 --- a/src/NRedisStack/Search/Extensions/IndexDataTypeExtensions.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using NRedisStack.Literals.Enums; - -namespace NRedisStack.Extensions -{ - internal static class IndexIndexDataType - { - public static string AsArg(this IndexDataType dataType) => dataType switch - { - IndexDataType.Hash => "HASH", - IndexDataType.Json => "JSON", - _ => throw new ArgumentOutOfRangeException(nameof(dataType), "Invalid Index DataType"), - }; - - // TODO: needed? - // public static IndexDataType AsDataType(string dataType) => dataType switch - // { - // "HASH" => IndexDataType.Hash, - // "JSON" => IndexDataType.Json, - // _ => throw new ArgumentOutOfRangeException(nameof(dataType), $"Invalid Index DataType '{dataType}'"), - // }; - } -} \ No newline at end of file diff --git a/src/NRedisStack/Search/FT.CREATE/FTCreateParams.cs b/src/NRedisStack/Search/FT.CREATE/FTCreateParams.cs index 755a86f1..96c56236 100644 --- a/src/NRedisStack/Search/FT.CREATE/FTCreateParams.cs +++ b/src/NRedisStack/Search/FT.CREATE/FTCreateParams.cs @@ -225,7 +225,7 @@ public void AddParams(List args) if (dataType != default(IndexDataType)) { args.Add("ON"); - args.Add(dataType.AsArg()); + args.Add(dataType.ToString()); } if (prefixes != null) diff --git a/src/NRedisStack/Search/Literals/Enums/IndexDataType.cs b/src/NRedisStack/Search/Literals/Enums/IndexDataType.cs index 14298ebf..f699d843 100644 --- a/src/NRedisStack/Search/Literals/Enums/IndexDataType.cs +++ b/src/NRedisStack/Search/Literals/Enums/IndexDataType.cs @@ -2,8 +2,8 @@ namespace NRedisStack.Literals.Enums { public enum IndexDataType { - Hash, - Json, + HASH, + JSON, } } \ No newline at end of file diff --git a/tests/NRedisStack.Tests/Search/SearchTests.cs b/tests/NRedisStack.Tests/Search/SearchTests.cs index bc0b2da9..ae50f126 100644 --- a/tests/NRedisStack.Tests/Search/SearchTests.cs +++ b/tests/NRedisStack.Tests/Search/SearchTests.cs @@ -1348,7 +1348,7 @@ public void TestFTCreateParamsCommandBuilder() .AddTextField("title", 1.0) .AddTagField("category", separator: ";"); - var ftCreateParams = FTCreateParams.CreateParams().On(IndexDataType.Json) + var ftCreateParams = FTCreateParams.CreateParams().On(IndexDataType.JSON) .AddPrefix("doc:") .Filter("@category:{red}") .Language("English") From 9cdcf23741b879064572697184f0238d516b1e28 Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Wed, 4 Jan 2023 17:55:59 +0200 Subject: [PATCH 03/27] add TestQueryCommandBuilder --- src/NRedisStack/Search/Query.cs | 47 ++++++---- tests/NRedisStack.Tests/Search/SearchTests.cs | 93 +++++++++++++++++++ 2 files changed, 122 insertions(+), 18 deletions(-) diff --git a/src/NRedisStack/Search/Query.cs b/src/NRedisStack/Search/Query.cs index e0bcf33b..d865830a 100644 --- a/src/NRedisStack/Search/Query.cs +++ b/src/NRedisStack/Search/Query.cs @@ -1,7 +1,5 @@ -using System.Collections.Generic; -using System.Globalization; +using System.Globalization; using NRedisStack.Literals; -using NRedisStack.Search; using StackExchange.Redis; namespace NRedisStack.Search @@ -170,7 +168,7 @@ public HighlightTags(string open, string close) /// /// Set the query payload to be evaluated by the scoring function /// - public byte[] Payload { get; set; } + public string Payload { get; set; } // TODO: should this be a byte[]? // TODO: Check if I need to add here WITHSORTKEYS @@ -230,6 +228,10 @@ internal void SerializeRedisArgs(List args) if (WithScores) { args.Add("WITHSCORES"); + if (ExplainScore) + { + args.Add("EXPLAINSCORE"); // TODO: Check Why Jedis doesn't have it + } } if (WithPayloads) { @@ -245,11 +247,6 @@ internal void SerializeRedisArgs(List args) { args.Add("SCORER"); args.Add(Scorer); - - if (ExplainScore) - { - args.Add("EXPLAINSCORE"); // TODO: Check Why Jedis doesn't have it - } } if (_fields?.Length > 0) @@ -346,12 +343,13 @@ internal void SerializeRedisArgs(List args) } } - if (_keys?.Length > 0) - { - args.Add("INKEYS"); - args.Add(_keys.Length); - args.AddRange(_keys); - } + // TODO: why duplicate if? + // if (_keys?.Length > 0) + // { + // args.Add("INKEYS"); + // args.Add(_keys.Length); + // args.AddRange(_keys); + // } if (_returnFields?.Length > 0) { args.Add("RETURN"); @@ -440,7 +438,7 @@ public Query AddFilter(Filter f) /// /// the payload /// the query itself - public Query SetPayload(byte[] payload) + public Query SetPayload(string payload) { Payload = payload; return this; @@ -491,7 +489,7 @@ public Query SetWithScores(bool value = true) /// Set the query to return object payloads, if any were given /// /// the query itself - public Query SetWithPayload() + public Query SetWithPayloads() { WithPayloads = true; return this; @@ -518,6 +516,19 @@ public Query SetScorer(string scorer) Scorer = scorer; return this; } + + /// + /// returns a textual description of how the scores were calculated. + /// Using this options requires the WITHSCORES option. + /// + /// + /// + public Query SetExplainScore(bool explainScore = true) + { + ExplainScore = explainScore; + return this; + } + /// /// Limit the query to results that are limited to a specific set of fields /// @@ -678,4 +689,4 @@ public Query SetExpander(String field) return this; } } -} +} \ No newline at end of file diff --git a/tests/NRedisStack.Tests/Search/SearchTests.cs b/tests/NRedisStack.Tests/Search/SearchTests.cs index ae50f126..d60a89f5 100644 --- a/tests/NRedisStack.Tests/Search/SearchTests.cs +++ b/tests/NRedisStack.Tests/Search/SearchTests.cs @@ -1506,6 +1506,99 @@ public async Task TestFiltersAsync() Assert.Equal("doc1", res1.Documents[0].Id); } + [Fact] + public void TestQueryCommandBuilder() + { + var testQuery = new Query("foo").HighlightFields(new Query.HighlightTags("", ""), "txt") + .SetVerbatim() + .SetNoStopwords() + .SetWithScores() + .SetPayload("txt") + .SetLanguage("English") + .SetScorer("TFIDF") + .SetExplainScore() + .SetWithScores() + .SetWithPayloads() + .SetSortBy("txt", true) + .Limit(0, 10) + .SummarizeFields(20, 3, ";", "txt") + .LimitKeys("key1", "key2") + .ReturnFields("txt") + .AddParam("name", "value") + .Dialect(1) + .Slop(0) + .Timeout(1000) + .SetInOrder() + .SetExpander("myexpander"); + var buildCommand = SearchCommandBuilder.Search("idx", testQuery); + var expectedArgs = new List {"idx", + "foo", + "VERBATIM", + "NOSTOPWORDS", + "WITHSCORES", + "EXPLAINSCORE", + "WITHPAYLOADS", + "LANGUAGE", + "English", + "SCORER", + "TFIDF", + "SORTBY", + "txt", + "ASC", + "PAYLOAD", + "txt", + "HIGHLIGHT", + "FIELDS", + "1", + "txt", + "TAGS", + "", + "", + "SUMMARIZE", + "FIELDS", + "1", + "txt", + "FRAGS", + "3", + "LEN", + "20", + "SEPARATOR", + ";", + "INKEYS", + "2", + "key1", + "key2", + "RETURN", + "1", + "txt", + "PARAMS", + "2", + "name", + "value", + "DIALECT", + "1", + "SLOP", + "0", + "TIMEOUT", + "1000", + "INORDER", + "EXPANDER", + "myexpander"}; + + for(int i = 0; i < buildCommand.Args.Count(); i++) + { + Assert.Equal(expectedArgs[i].ToString(), buildCommand.Args[i].ToString()); + } + Assert.Equal("FT.SEARCH", buildCommand.Command); + // test that the command not throw an exception: + var db = redisFixture.Redis.GetDatabase(); + db.Execute("FLUSHALL"); + var ft = db.FT(); + ft.Create("idx", new FTCreateParams(), new Schema().AddTextField("txt")); + var res = ft.Search("idx", testQuery); + Assert.Equal(0, res.Documents.Count()); + } + [Fact] public void TestFieldsCommandBuilder() { From 52208ee575e2dea4224b2cd04a5eb3b019f683ef Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Thu, 5 Jan 2023 11:24:27 +0200 Subject: [PATCH 04/27] more cover to equal & ToString of graph data types --- .../Graph/DataTypes/GraphEntity.cs | 25 ++++++++++--------- tests/NRedisStack.Tests/Graph/GraphTests.cs | 18 +++++++++++++ 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/NRedisStack/Graph/DataTypes/GraphEntity.cs b/src/NRedisStack/Graph/DataTypes/GraphEntity.cs index 58a5391e..46383db6 100644 --- a/src/NRedisStack/Graph/DataTypes/GraphEntity.cs +++ b/src/NRedisStack/Graph/DataTypes/GraphEntity.cs @@ -59,22 +59,23 @@ public override int GetHashCode() } } + // TODO: Delete it? /// /// Overriden ToString that emits a string containing the ID and property map of the entity. /// /// - public override string ToString() - { - var sb = new StringBuilder(); - - sb.Append("GraphEntity{id="); - sb.Append(Id); - sb.Append(", propertyMap="); - sb.Append(PropertyMap); - sb.Append('}'); - - return sb.ToString(); - } + // public override string ToString() + // { + // var sb = new StringBuilder(); + + // sb.Append("GraphEntity{id="); + // sb.Append(Id); + // sb.Append(", propertyMap="); + // sb.Append(PropertyMap); + // sb.Append('}'); + + // return sb.ToString(); + // } public string PropertyMapToString() { diff --git a/tests/NRedisStack.Tests/Graph/GraphTests.cs b/tests/NRedisStack.Tests/Graph/GraphTests.cs index 211d6702..7d8b4281 100644 --- a/tests/NRedisStack.Tests/Graph/GraphTests.cs +++ b/tests/NRedisStack.Tests/Graph/GraphTests.cs @@ -1953,7 +1953,12 @@ public void TestEquals() Assert.False(edge1.Equals(edge2)); Assert.False(node1.Equals(node2)); Assert.True(edge1.Equals(edge1Copy)); + Assert.True(edge1.Equals(edge1)); Assert.True(node1.Equals(node1Copy)); + Assert.True(node1.Equals(node1)); + Assert.False(node1.Equals(edge1)); + Assert.False(edge1.Equals(node1)); + var path = new NRedisStack.Graph.DataTypes.Path(new List() { node1, node2 }, new List() { edge1, edge2 }); @@ -1962,7 +1967,20 @@ public void TestEquals() var path2 = new NRedisStack.Graph.DataTypes.Path(new List() { node1, node2 }, new List() { edge1 }); Assert.True(path.Equals(pathCopy)); + Assert.True(path.Equals(path)); Assert.False(path.Equals(path2)); + Assert.False(path.Equals(node1)); + + var node1String = node1.ToString(); + var edge1String = edge1.ToString(); + var pathString = path.ToString(); + var expectedNode1String = "Node{labels=[], id=1, propertyMap={}}"; + var expectedEdge1String = "Edge{relationshipType='', source=0, destination=0, id=1, propertyMap={}}"; + var expectedPathString = "Path{nodes=System.Collections.ObjectModel.ReadOnlyCollection`1[NRedisStack.Graph.DataTypes.Node], edges=System.Collections.ObjectModel.ReadOnlyCollection`1[NRedisStack.Graph.DataTypes.Edge]}"; + Assert.Equal(expectedNode1String, node1String); + Assert.Equal(expectedEdge1String, edge1String); + Assert.Equal(expectedPathString, pathString); + } #endregion From 9c1d4dd7fc7b5eafd57a572a151b425f5edeac7c Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Thu, 5 Jan 2023 12:22:09 +0200 Subject: [PATCH 05/27] cover more equal/ToString/Hash functions --- tests/NRedisStack.Tests/Graph/GraphTests.cs | 50 ++++++++++++++++++++- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/tests/NRedisStack.Tests/Graph/GraphTests.cs b/tests/NRedisStack.Tests/Graph/GraphTests.cs index 7d8b4281..70ea6e5b 100644 --- a/tests/NRedisStack.Tests/Graph/GraphTests.cs +++ b/tests/NRedisStack.Tests/Graph/GraphTests.cs @@ -782,7 +782,20 @@ private void AssertTestGeoPoint(IGraphCommands graph) Node node = record.Current.GetValue(0); var property = node.PropertyMap["location"]; - Assert.Equal((object)(new Point(30.27822306, -97.75134723)), property); + var point = new Point(30.27822306, -97.75134723); + Assert.Equal((object)(point), property); + } + + [Fact] + public void TestPoint() + { + var point = new Point(30.27822306, -97.75134723); + + var pointString = point.ToString(); + Assert.Equal("Point{latitude=30.27822306, longitude=-97.75134723}", pointString); + var pointHash = point.GetHashCode(); + Assert.Equal(847819990, pointHash); + Assert.Throws(() => new Point(new List { 1, 2, 3 })); } [Fact] @@ -1934,22 +1947,44 @@ public async Task TestModulePrefixs1Async() } [Fact] - public void TestEquals() + public void TestEqualsAndToString() { IDatabase db = redisFixture.Redis.GetDatabase(); db.Execute("FLUSHALL"); + var graph = db.GRAPH(); + ResultSet resultSet1 = graph.Query("db", "RETURN 10^100000"); + ResultSet resultSet2 = graph.Query("db", "RETURN 10^1000"); + var iterator1 = resultSet1.GetEnumerator(); + Assert.True(iterator1.MoveNext()); + var record1 = iterator1.Current; + var iterator2 = resultSet2.GetEnumerator(); + Assert.True(iterator2.MoveNext()); + var record2 = iterator2.Current; + + Assert.True(resultSet1.Header.Equals(resultSet1.Header)); + Assert.False(resultSet1.Header.Equals(resultSet2.Header)); + Assert.False(resultSet1.Header.Equals(new object())); + Assert.False(resultSet1.Header.Equals(null)); + + Assert.True(record1.Equals(record1)); + Assert.False(record1.Equals(record2)); + Assert.False(record1.Equals(new object())); + Assert.False(record1.Equals(null)); + var edge1 = new Edge(); var edge1Copy = new Edge(); var edge2 = new Edge(); var node1 = new Node(); var node1Copy = new Node(); var node2 = new Node(); + edge1.Id = 1; edge1Copy.Id = 1; edge2.Id = 2; node1.Id = 1; node1Copy.Id = 1; node2.Id = 2; + Assert.False(edge1.Equals(edge2)); Assert.False(node1.Equals(node2)); Assert.True(edge1.Equals(edge1Copy)); @@ -1958,6 +1993,9 @@ public void TestEquals() Assert.True(node1.Equals(node1)); Assert.False(node1.Equals(edge1)); Assert.False(edge1.Equals(node1)); + Assert.False(node1.Equals(null)); + Assert.False(edge1.Equals(null)); + var path = new NRedisStack.Graph.DataTypes.Path(new List() { node1, node2 }, @@ -1971,6 +2009,14 @@ public void TestEquals() Assert.False(path.Equals(path2)); Assert.False(path.Equals(node1)); + var recod1String = record1.ToString(); + var recod2Hash = record2.GetHashCode(); + var expectedRecod1String = "Record{values=∞}"; + var expectedRecod2Hash = 1275355212; + + Assert.Equal(expectedRecod1String, recod1String); + Assert.Equal(expectedRecod2Hash, recod2Hash); + var node1String = node1.ToString(); var edge1String = edge1.ToString(); var pathString = path.ToString(); From 6bcb7c13b318111fbb8e6da3db9bea8925b64dd1 Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Thu, 5 Jan 2023 12:25:09 +0200 Subject: [PATCH 06/27] fix test --- tests/NRedisStack.Tests/Graph/GraphTests.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/NRedisStack.Tests/Graph/GraphTests.cs b/tests/NRedisStack.Tests/Graph/GraphTests.cs index 70ea6e5b..c2849d00 100644 --- a/tests/NRedisStack.Tests/Graph/GraphTests.cs +++ b/tests/NRedisStack.Tests/Graph/GraphTests.cs @@ -2010,12 +2010,10 @@ public void TestEqualsAndToString() Assert.False(path.Equals(node1)); var recod1String = record1.ToString(); - var recod2Hash = record2.GetHashCode(); var expectedRecod1String = "Record{values=∞}"; - var expectedRecod2Hash = 1275355212; Assert.Equal(expectedRecod1String, recod1String); - Assert.Equal(expectedRecod2Hash, recod2Hash); + Assert.NotEqual(record2.GetHashCode(), record1.GetHashCode()); var node1String = node1.ToString(); var edge1String = edge1.ToString(); From be145f95807a12150c99cedf525baa80886769c9 Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Thu, 5 Jan 2023 12:34:14 +0200 Subject: [PATCH 07/27] fix infinity --- tests/NRedisStack.Tests/Graph/GraphTests.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/NRedisStack.Tests/Graph/GraphTests.cs b/tests/NRedisStack.Tests/Graph/GraphTests.cs index c2849d00..2208572f 100644 --- a/tests/NRedisStack.Tests/Graph/GraphTests.cs +++ b/tests/NRedisStack.Tests/Graph/GraphTests.cs @@ -2009,10 +2009,7 @@ public void TestEqualsAndToString() Assert.False(path.Equals(path2)); Assert.False(path.Equals(node1)); - var recod1String = record1.ToString(); - var expectedRecod1String = "Record{values=∞}"; - - Assert.Equal(expectedRecod1String, recod1String); + Assert.True(record1.ToString() == "Record{values=Infinity}" || record1.ToString() == "Record{values=∞}"); Assert.NotEqual(record2.GetHashCode(), record1.GetHashCode()); var node1String = node1.ToString(); From 308fa09e57bf973b4b96b57835995e8424af45f6 Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Thu, 5 Jan 2023 13:41:07 +0200 Subject: [PATCH 08/27] start covering command builder --- src/NRedisStack/Graph/GraphCommandBuilder.cs | 1 - tests/NRedisStack.Tests/Graph/GraphTests.cs | 10 ++++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/NRedisStack/Graph/GraphCommandBuilder.cs b/src/NRedisStack/Graph/GraphCommandBuilder.cs index ed56b4dd..a2d259ff 100644 --- a/src/NRedisStack/Graph/GraphCommandBuilder.cs +++ b/src/NRedisStack/Graph/GraphCommandBuilder.cs @@ -1,6 +1,5 @@ using NRedisStack.Literals; using NRedisStack.RedisStackCommands; -using static NRedisStack.Graph.RedisGraphUtilities; namespace NRedisStack { diff --git a/tests/NRedisStack.Tests/Graph/GraphTests.cs b/tests/NRedisStack.Tests/Graph/GraphTests.cs index 2208572f..b1ff64c1 100644 --- a/tests/NRedisStack.Tests/Graph/GraphTests.cs +++ b/tests/NRedisStack.Tests/Graph/GraphTests.cs @@ -2021,7 +2021,17 @@ public void TestEqualsAndToString() Assert.Equal(expectedNode1String, node1String); Assert.Equal(expectedEdge1String, edge1String); Assert.Equal(expectedPathString, pathString); + } + [Fact] + public void TestPrepareQuery() + { + var graph = redisFixture.Redis.GetDatabase().GRAPH(); + var res1 = graph.Query("graph", "RETURN 1", new Dictionary { { "a", (char)'c' } }); + var res2 = graph.Query("graph", "RETURN 1", new Dictionary { { "a", null } }); + var res3 = graph.Query("graph", "RETURN 1", new Dictionary { { "a", new string[]{"foo", "bar"} } }); + var res4 = graph.Query("graph", "RETURN 1", new Dictionary { { "a", new List{"foo2", "bar2"} } }); + // TODO: complete this test } #endregion From b739bc9733d739a38ceec867a2feb3aae5fbb0dd Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Thu, 5 Jan 2023 19:35:31 +0200 Subject: [PATCH 09/27] Add TestInsertArgsError --- tests/NRedisStack.Tests/Bloom/BloomTests.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/NRedisStack.Tests/Bloom/BloomTests.cs b/tests/NRedisStack.Tests/Bloom/BloomTests.cs index 33bd5135..87071027 100644 --- a/tests/NRedisStack.Tests/Bloom/BloomTests.cs +++ b/tests/NRedisStack.Tests/Bloom/BloomTests.cs @@ -347,10 +347,21 @@ public void TestModulePrefixs1() var conn = ConnectionMultiplexer.Connect("localhost"); IDatabase db = conn.GetDatabase(); - var bf = db.FT(); + var bf = db.FT(); // ... conn.Dispose(); } + } + [Fact] + public void TestInsertArgsError() + { + IDatabase db = redisFixture.Redis.GetDatabase(); + db.Execute("FLUSHALL"); + var bf = db.BF(); + + RedisValue[] items = new RedisValue[] { "item1", "item2", "item3" }; + // supose to throw exception: + Assert.Throws(() => bf.Insert("key3", items, 100, 0.01, 2, nocreate: true, nonscaling: true)); } } \ No newline at end of file From 1aa650965c614c17488d6ad2c874bd02958de0ba Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Sun, 8 Jan 2023 16:35:28 +0200 Subject: [PATCH 10/27] Cover Reducer --- src/NRedisStack/Search/AggregationResult.cs | 5 +- src/NRedisStack/Search/Reducers.cs | 4 +- tests/NRedisStack.Tests/Search/SearchTests.cs | 110 +++++++++++++++++- 3 files changed, 114 insertions(+), 5 deletions(-) diff --git a/src/NRedisStack/Search/AggregationResult.cs b/src/NRedisStack/Search/AggregationResult.cs index 03545895..bd3af50a 100644 --- a/src/NRedisStack/Search/AggregationResult.cs +++ b/src/NRedisStack/Search/AggregationResult.cs @@ -26,8 +26,9 @@ internal AggregationResult(RedisResult result, long cursorId = -1) { var key = (string)raw[j++]; var val = raw[j++]; - if (val.Type != ResultType.MultiBulk) - cur.Add(key, (RedisValue)val); + if (val.Type == ResultType.MultiBulk) + continue; // TODO: handle multi-bulk (maybe change to object?) + cur.Add(key, (RedisValue)val); } _results[i - 1] = cur; } diff --git a/src/NRedisStack/Search/Reducers.cs b/src/NRedisStack/Search/Reducers.cs index 6e8254dd..c5e23f06 100644 --- a/src/NRedisStack/Search/Reducers.cs +++ b/src/NRedisStack/Search/Reducers.cs @@ -54,7 +54,7 @@ protected override void AddOwnArgs(List args) } public override string Name => "QUANTILE"; } - public static Reducer FirstValue(string field, SortedField sortBy) => new FirstValueReducer(field, sortBy); + public static Reducer FirstValue(string field, SortedField? sortBy) => new FirstValueReducer(field, sortBy); private sealed class FirstValueReducer : Reducer { private readonly SortedField? _sortBy; @@ -78,7 +78,7 @@ protected override void AddOwnArgs(List args) } } } - public static Reducer FirstValue(string field) => new FirstValueReducer(field, null); + public static Reducer FirstValue(string field) => FirstValue(field, null); public static Reducer ToList(string field) => new SingleFieldReducer("TOLIST", field); diff --git a/tests/NRedisStack.Tests/Search/SearchTests.cs b/tests/NRedisStack.Tests/Search/SearchTests.cs index d60a89f5..88bd8b97 100644 --- a/tests/NRedisStack.Tests/Search/SearchTests.cs +++ b/tests/NRedisStack.Tests/Search/SearchTests.cs @@ -967,6 +967,114 @@ public async Task TestCursorAsync() catch (RedisException) { } } + [Fact] + public void TestAggregationGroupBy() + { + IDatabase db = redisFixture.Redis.GetDatabase(); + db.Execute("FLUSHALL"); + var ft = db.FT(); + + // Creating the index definition and schema + ft.Create("idx", new FTCreateParams(), new Schema().AddNumericField("random_num") + .AddTextField("title") + .AddTextField("body") + .AddTextField("parent")); + + // Indexing a document + AddDocument(db, "search", new Dictionary(){ + { "title", "RediSearch" }, + { "body", "Redisearch impements a search engine on top of redis" }, + { "parent", "redis" }, + { "random_num", 10 }}); + + AddDocument(db, "ai", new Dictionary + { + { "title", "RedisAI" }, + { "body", "RedisAI executes Deep Learning/Machine Learning models and managing their data." }, + { "parent", "redis" }, + { "random_num", 3 }}); + + AddDocument(db, "json", new Dictionary + { + { "title", "RedisJson" }, + { "body", "RedisJSON implements ECMA-404 The JSON Data Interchange Standard as a native data type." }, + { "parent", "redis" }, + { "random_num", 8 }}); + + var req = new AggregationRequest("redis").GroupBy("@parent", Reducers.Count()); + var res = ft.Aggregate("idx", req).GetRow(0); + Assert.True(res.ContainsKey("parent")); + Assert.Equal(res["parent"], "redis"); + Assert.Equal(res["__generated_aliascount"], "3"); + + req = new AggregationRequest("redis").GroupBy("@parent", Reducers.CountDistinct("@title")); + res = ft.Aggregate("idx", req).GetRow(0); + Assert.Equal(res["parent"], "redis"); + Assert.Equal(res.GetLong("__generated_aliascount_distincttitle"), 3); + + req = new AggregationRequest("redis").GroupBy("@parent", Reducers.CountDistinctish("@title")); + res = ft.Aggregate("idx", req).GetRow(0); + Assert.Equal(res["parent"], "redis"); + Assert.Equal(res.GetLong("__generated_aliascount_distinctishtitle"), 3); + + req = new AggregationRequest("redis").GroupBy("@parent", Reducers.Sum("@random_num")); + res = ft.Aggregate("idx", req).GetRow(0); + Assert.Equal(res["parent"], "redis"); + Assert.Equal(res.GetLong("__generated_aliassumrandom_num"), 21); // 10+8+3 + + req = new AggregationRequest("redis").GroupBy("@parent", Reducers.Min("@random_num")); + res = ft.Aggregate("idx", req).GetRow(0); + Assert.Equal(res["parent"], "redis"); + Assert.Equal(res.GetLong("__generated_aliasminrandom_num"), 3); // min(10,8,3) + + req = new AggregationRequest("redis").GroupBy("@parent", Reducers.Max("@random_num")); + res = ft.Aggregate("idx", req).GetRow(0); + Assert.Equal(res["parent"], "redis"); + Assert.Equal(res.GetLong("__generated_aliasmaxrandom_num"), 10); // max(10,8,3) + + req = new AggregationRequest("redis").GroupBy("@parent", Reducers.Avg("@random_num")); + res = ft.Aggregate("idx", req).GetRow(0); + Assert.Equal(res["parent"], "redis"); + Assert.Equal(res.GetLong("__generated_aliasavgrandom_num"), 7); // (10+3+8)/3 + + req = new AggregationRequest("redis").GroupBy("@parent", Reducers.StdDev("@random_num")); + res = ft.Aggregate("idx", req).GetRow(0); + Assert.Equal(res["parent"], "redis"); + Assert.Equal(res.GetDouble("__generated_aliasstddevrandom_num"), 3.60555127546); + + req = new AggregationRequest("redis").GroupBy( + "@parent", Reducers.Quantile("@random_num", 0.5)); + res = ft.Aggregate("idx", req).GetRow(0); + Assert.Equal(res["parent"], "redis"); + Assert.Equal(res.GetLong("__generated_aliasquantilerandom_num,0.5"), 8); // median of 3,8,10 + + req = new AggregationRequest("redis").GroupBy( + "@parent", Reducers.ToList("@title")); + var rawRes = ft.Aggregate("idx", req); + res = rawRes.GetRow(0); + Assert.Equal(res["parent"], "redis"); + // TODO: complete this assert after handling multi bulk reply + //Assert.Equal((RedisValue[])res["__generated_aliastolisttitle"], { "RediSearch", "RedisAI", "RedisJson"}); + + req = new AggregationRequest("redis").GroupBy( + "@parent", Reducers.FirstValue("@title").As("first")); + res = ft.Aggregate("idx", req).GetRow(0); + Assert.Equal(res["parent"], "redis"); + Assert.Equal(res["first"], "RediSearch"); + + req = new AggregationRequest("redis").GroupBy( + "@parent", Reducers.RandomSample("@title", 2).As("random")); + res = ft.Aggregate("idx", req).GetRow(0); + Assert.Equal(res["parent"], "redis"); + // TODO: complete this assert after handling multi bulk reply + // Assert.Equal(res[2], "random"); + // Assert.Equal(len(res[3]), 2); + // Assert.Equal(res[3][0] in ["RediSearch", "RedisAI", "RedisJson"]); + // req = new AggregationRequest("redis").GroupBy("@parent", redu + + } + + [Fact] public void TestDictionary() { @@ -1585,7 +1693,7 @@ public void TestQueryCommandBuilder() "EXPANDER", "myexpander"}; - for(int i = 0; i < buildCommand.Args.Count(); i++) + for (int i = 0; i < buildCommand.Args.Count(); i++) { Assert.Equal(expectedArgs[i].ToString(), buildCommand.Args[i].ToString()); } From ff1150e0b4bf70b58f2102b562494ab4d7e618f0 Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Mon, 9 Jan 2023 14:40:49 +0200 Subject: [PATCH 11/27] Cover Document --- src/NRedisStack/Search/Document.cs | 23 ++++++------ tests/NRedisStack.Tests/Search/SearchTests.cs | 35 ++++++++++--------- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/NRedisStack/Search/Document.cs b/src/NRedisStack/Search/Document.cs index 96880700..8ead80d7 100644 --- a/src/NRedisStack/Search/Document.cs +++ b/src/NRedisStack/Search/Document.cs @@ -65,18 +65,19 @@ public RedisValue this[string key] public bool HasProperty(string key) => _properties.ContainsKey(key); - internal static Document Parse(string docId, RedisResult result) - { - if (result == null || result.IsNull) return null; - var arr = (RedisResult[])result; - var doc = new Document(docId); + // TODO: check if this is needed: + // internal static Document Parse(string docId, RedisResult result) + // { + // if (result == null || result.IsNull) return null; + // var arr = (RedisResult[])result; + // var doc = new Document(docId); - for(int i = 0; i < arr.Length; ) - { - doc[(string)arr[i++]] = (RedisValue)arr[i++]; - } - return doc; - } + // for(int i = 0; i < arr.Length; ) + // { + // doc[(string)arr[i++]] = (RedisValue)arr[i++]; + // } + // return doc; + // } public Document Set(string field, RedisValue value) { diff --git a/tests/NRedisStack.Tests/Search/SearchTests.cs b/tests/NRedisStack.Tests/Search/SearchTests.cs index 88bd8b97..53b361b4 100644 --- a/tests/NRedisStack.Tests/Search/SearchTests.cs +++ b/tests/NRedisStack.Tests/Search/SearchTests.cs @@ -24,22 +24,25 @@ public void Dispose() private void AddDocument(IDatabase db, Document doc) { - string key = doc.Id; - var properties = doc.GetProperties(); - // HashEntry[] hash = new HashEntry[properties.Count()]; - // for(int i = 0; i < properties.Count(); i++) - // { - // var property = properties.ElementAt(i); - // hash[i] = new HashEntry(property.Key, property.Value); - // } - // db.HashSet(key, hash); - var nameValue = new List() { key }; - foreach (var item in properties) + if (doc.HasProperty(doc.Id)) { - nameValue.Add(item.Key); - nameValue.Add(item.Value); + string key = doc.Id; + var properties = doc.GetProperties(); + // HashEntry[] hash = new HashEntry[properties.Count()]; + // for(int i = 0; i < properties.Count(); i++) + // { + // var property = properties.ElementAt(i); + // hash[i] = new HashEntry(property.Key, property.Value); + // } + // db.HashSet(key, hash); + var nameValue = new List() { key }; + foreach (var item in properties) + { + nameValue.Add(item.Key); + nameValue.Add(item.Value); + } + db.Execute("HSET", nameValue); } - db.Execute("HSET", nameValue); } @@ -118,7 +121,7 @@ public void TestAggregationRequestTimeout() sc.AddTextField("name", 1.0, sortable: true); sc.AddNumericField("count", sortable: true); ft.Create(index, FTCreateParams.CreateParams(), sc); - AddDocument(db, new Document("data1").Set("name", "abc").Set("count", 10)); + AddDocument(db, new Document("data1").Set("name", "abc").Set("count", 10).SetScore(1.0)); AddDocument(db, new Document("data2").Set("name", "def").Set("count", 5)); AddDocument(db, new Document("data3").Set("name", "def").Set("count", 25)); @@ -140,7 +143,7 @@ public async Task TestAggregationRequestTimeoutAsync() sc.AddTextField("name", 1.0, sortable: true); sc.AddNumericField("count", sortable: true); ft.Create(index, FTCreateParams.CreateParams(), sc); - AddDocument(db, new Document("data1").Set("name", "abc").Set("count", 10)); + AddDocument(db, new Document("data1").Set("name", "abc").Set("count", 10).SetScore(1.0)); AddDocument(db, new Document("data2").Set("name", "def").Set("count", 5)); AddDocument(db, new Document("data3").Set("name", "def").Set("count", 25)); From abbb0fb2edb25b8ef8dcf73f5c4cdf369beae31d Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Mon, 9 Jan 2023 15:53:37 +0200 Subject: [PATCH 12/27] Cover limit --- src/NRedisStack/Search/AggregationRequest.cs | 7 ++- src/NRedisStack/Search/Document.cs | 4 +- src/NRedisStack/Search/FieldName.cs | 20 ++++----- src/NRedisStack/Search/Group.cs | 15 ++++--- src/NRedisStack/Search/SortedField.cs | 6 +-- tests/NRedisStack.Tests/Search/SearchTests.cs | 44 +++++++++++++++++-- 6 files changed, 64 insertions(+), 32 deletions(-) diff --git a/src/NRedisStack/Search/AggregationRequest.cs b/src/NRedisStack/Search/AggregationRequest.cs index d8b56c53..e6d5f705 100644 --- a/src/NRedisStack/Search/AggregationRequest.cs +++ b/src/NRedisStack/Search/AggregationRequest.cs @@ -52,10 +52,9 @@ public AggregationRequest Limit(int offset, int count) return this; } - public AggregationRequest Limit(int count) - { - return Limit(0, count); - } + public AggregationRequest Limit(int count) => Limit(0, count); + + public AggregationRequest SortBy(string property) => SortBy(SortedField.Asc(property)); public AggregationRequest SortBy(params SortedField[] Fields) { diff --git a/src/NRedisStack/Search/Document.cs b/src/NRedisStack/Search/Document.cs index 8ead80d7..472b6c00 100644 --- a/src/NRedisStack/Search/Document.cs +++ b/src/NRedisStack/Search/Document.cs @@ -63,9 +63,9 @@ public RedisValue this[string key] internal set { _properties[key] = value; } } - public bool HasProperty(string key) => _properties.ContainsKey(key); - // TODO: check if this is needed: + //public bool HasProperty(string key) => _properties.ContainsKey(key); + // internal static Document Parse(string docId, RedisResult result) // { // if (result == null || result.IsNull) return null; diff --git a/src/NRedisStack/Search/FieldName.cs b/src/NRedisStack/Search/FieldName.cs index e277a30f..f107c784 100644 --- a/src/NRedisStack/Search/FieldName.cs +++ b/src/NRedisStack/Search/FieldName.cs @@ -1,6 +1,3 @@ -using System.Collections.Generic; -using System.Text; - namespace NRedisStack.Search { public class FieldName @@ -40,14 +37,15 @@ public FieldName As(string attribute) return this; } - public static FieldName[] convert(params string[] names) - { - if (names == null) return null; - FieldName[] fields = new FieldName[names.Length]; - for (int i = 0; i < names.Length; i++) - fields[i] = FieldName.Of(names[i]); + // TODO: check if this is needed: + // public static FieldName[] Convert(params string[] names) + // { + // if (names == null) return null; + // FieldName[] fields = new FieldName[names.Length]; + // for (int i = 0; i < names.Length; i++) + // fields[i] = FieldName.Of(names[i]); - return fields; - } + // return fields; + // } } } \ No newline at end of file diff --git a/src/NRedisStack/Search/Group.cs b/src/NRedisStack/Search/Group.cs index 36bca902..50d14fc6 100644 --- a/src/NRedisStack/Search/Group.cs +++ b/src/NRedisStack/Search/Group.cs @@ -7,7 +7,7 @@ public class Group private readonly IList _reducers = new List(); private readonly IList _fields; - private Limit _limit = new Limit(0, 0); + private Limit _limit = Aggregation.Limit.NO_LIMIT; public Group(params string[] fields) => _fields = fields; public Group(IList fields) => _fields = fields; @@ -44,11 +44,12 @@ internal void SerializeRedisArgs(List args) _limit.SerializeRedisArgs(args); } - public List getArgs() - { - List args = new List(); - SerializeRedisArgs(args); - return args; - } + // TODO: check if this is needed: + // public List getArgs() + // { + // List args = new List(); + // SerializeRedisArgs(args); + // return args; + // } } } \ No newline at end of file diff --git a/src/NRedisStack/Search/SortedField.cs b/src/NRedisStack/Search/SortedField.cs index 6aa3022a..dc9c1e5c 100644 --- a/src/NRedisStack/Search/SortedField.cs +++ b/src/NRedisStack/Search/SortedField.cs @@ -1,6 +1,4 @@ -using System.Collections.Generic; - -namespace NRedisStack.Search.Aggregation +namespace NRedisStack.Search.Aggregation { public class SortedField { @@ -13,7 +11,7 @@ public enum SortOrder public string FieldName { get; } public SortOrder Order { get; } - public SortedField(String fieldName, SortOrder order) + public SortedField(String fieldName, SortOrder order = SortOrder.ASC) { this.FieldName = fieldName; this.Order = order; diff --git a/tests/NRedisStack.Tests/Search/SearchTests.cs b/tests/NRedisStack.Tests/Search/SearchTests.cs index 53b361b4..c2f40c64 100644 --- a/tests/NRedisStack.Tests/Search/SearchTests.cs +++ b/tests/NRedisStack.Tests/Search/SearchTests.cs @@ -24,8 +24,6 @@ public void Dispose() private void AddDocument(IDatabase db, Document doc) { - if (doc.HasProperty(doc.Id)) - { string key = doc.Id; var properties = doc.GetProperties(); // HashEntry[] hash = new HashEntry[properties.Count()]; @@ -42,8 +40,6 @@ private void AddDocument(IDatabase db, Document doc) nameValue.Add(item.Value); } db.Execute("HSET", nameValue); - } - } private void AddDocument(IDatabase db, string key, Dictionary objDictionary) @@ -1765,6 +1761,46 @@ public void TestFieldsCommandBuilder() } } + [Fact] + public void TestLimit() + { + IDatabase db = redisFixture.Redis.GetDatabase(); + db.Execute("FLUSHALL"); + var ft = db.FT(); + + ft.Create("idx", new FTCreateParams(), new Schema().AddTextField("t1").AddTextField("t2")); + Document doc1 = new Document("doc1", new Dictionary {{"t1", "a"}, {"t2", "b"}}); + Document doc2 = new Document("doc2", new Dictionary {{"t1", "b"}, {"t2", "a"}}); + AddDocument(db, doc1); + AddDocument(db, doc2); + + var req = new AggregationRequest("*").SortBy("@t1").Limit(1, 1); + var res = ft.Aggregate("idx", req); + + Assert.Equal( res.GetResults().Count, 1); + Assert.Equal( res.GetResults()[0]["t1"].ToString(), "b"); + } + + [Fact] + public async Task TestLimitAsync() + { + IDatabase db = redisFixture.Redis.GetDatabase(); + db.Execute("FLUSHALL"); + var ft = db.FT(); + + ft.Create("idx", new FTCreateParams(), new Schema().AddTextField("t1").AddTextField("t2")); + Document doc1 = new Document("doc1", new Dictionary {{"t1", "a"}, {"t2", "b"}}); + Document doc2 = new Document("doc2", new Dictionary {{"t1", "b"}, {"t2", "a"}}); + AddDocument(db, doc1); + AddDocument(db, doc2); + + var req = new AggregationRequest("*").SortBy("@t1").Limit(1, 1); + var res = await ft.AggregateAsync("idx", req); + + Assert.Equal( res.GetResults().Count, 1); + Assert.Equal( res.GetResults()[0]["t1"].ToString(), "b"); + } + [Fact] public void TestModulePrefixs1() { From 6c185d3755e28838ec402c14fff95a306bb588bf Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Mon, 9 Jan 2023 17:43:41 +0200 Subject: [PATCH 13/27] Delete ExplainScore --- src/NRedisStack/Search/Query.cs | 33 ++++++++++--------- src/NRedisStack/Search/Reducer.cs | 28 ++++++++-------- src/NRedisStack/Search/SearchCommands.cs | 4 +-- src/NRedisStack/Search/SearchResult.cs | 22 ++++++------- tests/NRedisStack.Tests/Search/SearchTests.cs | 18 ++++++++-- 5 files changed, 59 insertions(+), 46 deletions(-) diff --git a/src/NRedisStack/Search/Query.cs b/src/NRedisStack/Search/Query.cs index d865830a..1a73232c 100644 --- a/src/NRedisStack/Search/Query.cs +++ b/src/NRedisStack/Search/Query.cs @@ -189,7 +189,7 @@ public HighlightTags(string open, string close) /// Set the query scoring. see https://oss.redislabs.com/redisearch/Scoring.html for documentation /// public string Scorer { get; set; } - public bool ExplainScore { get; set; } // TODO: Check if this is needed because Jedis doesn't have it + // public bool ExplainScore { get; set; } // TODO: Check if this is needed because Jedis doesn't have it private Dictionary _params = null; private int _dialect = 0; @@ -228,10 +228,10 @@ internal void SerializeRedisArgs(List args) if (WithScores) { args.Add("WITHSCORES"); - if (ExplainScore) - { - args.Add("EXPLAINSCORE"); // TODO: Check Why Jedis doesn't have it - } + // if (ExplainScore) + // { + // args.Add("EXPLAINSCORE"); // TODO: Check Why Jedis doesn't have it + // } } if (WithPayloads) { @@ -517,17 +517,18 @@ public Query SetScorer(string scorer) return this; } - /// - /// returns a textual description of how the scores were calculated. - /// Using this options requires the WITHSCORES option. - /// - /// - /// - public Query SetExplainScore(bool explainScore = true) - { - ExplainScore = explainScore; - return this; - } + // TODO: check if this is needed (Jedis doesn't have it) + // /// + // /// returns a textual description of how the scores were calculated. + // /// Using this options requires the WITHSCORES option. + // /// + // /// + // /// + // public Query SetExplainScore(bool explainScore = true) + // { + // ExplainScore = explainScore; + // return this; + // } /// /// Limit the query to results that are limited to a specific set of fields diff --git a/src/NRedisStack/Search/Reducer.cs b/src/NRedisStack/Search/Reducer.cs index 212de35c..f9cb7b8c 100644 --- a/src/NRedisStack/Search/Reducer.cs +++ b/src/NRedisStack/Search/Reducer.cs @@ -4,9 +4,6 @@ namespace NRedisStack.Search.Aggregation { public abstract class Reducer { - - public override string ToString() => Name; - // internal Reducer(string field) => _field = field; /// @@ -57,11 +54,13 @@ public Reducer As(string alias) Alias = alias; return this; } - public Reducer SetAliasAsField() - { - if (string.IsNullOrEmpty(_field)) throw new InvalidOperationException("Cannot set to field name since no field exists"); - return As(_field); - } + + // TODO: check if this is needed: + // public Reducer SetAliasAsField() + // { + // if (string.IsNullOrEmpty(_field)) throw new InvalidOperationException("Cannot set to field name since no field exists"); + // return As(_field); + // } internal void SerializeRedisArgs(List args) { @@ -74,12 +73,13 @@ internal void SerializeRedisArgs(List args) throw new InvalidOperationException($"Reducer '{ToString()}' incorrectly reported the arg-count as {count}, but added {after - before}"); } - public List GetArgs() - { - List args = new List(); - SerializeRedisArgs(args); - return args; - } + // TODO: check if this is needed: + // public List GetArgs() + // { + // List args = new List(); + // SerializeRedisArgs(args); + // return args; + // } } } \ No newline at end of file diff --git a/src/NRedisStack/Search/SearchCommands.cs b/src/NRedisStack/Search/SearchCommands.cs index c81b29df..26b2a525 100644 --- a/src/NRedisStack/Search/SearchCommands.cs +++ b/src/NRedisStack/Search/SearchCommands.cs @@ -254,14 +254,14 @@ public async Task InfoAsync(RedisValue index) => public SearchResult Search(string indexName, Query q) { var resp = _db.Execute(SearchCommandBuilder.Search(indexName, q)).ToArray(); - return new SearchResult(resp, !q.NoContent, q.WithScores, q.WithPayloads, q.ExplainScore); + return new SearchResult(resp, !q.NoContent, q.WithScores, q.WithPayloads/*, q.ExplainScore*/); } /// public async Task SearchAsync(string indexName, Query q) { var resp = (await _db.ExecuteAsync(SearchCommandBuilder.Search(indexName, q))).ToArray(); - return new SearchResult(resp, !q.NoContent, q.WithScores, q.WithPayloads, q.ExplainScore); + return new SearchResult(resp, !q.NoContent, q.WithScores, q.WithPayloads/*, q.ExplainScore*/); } /// diff --git a/src/NRedisStack/Search/SearchResult.cs b/src/NRedisStack/Search/SearchResult.cs index a8ea49d3..029f1533 100644 --- a/src/NRedisStack/Search/SearchResult.cs +++ b/src/NRedisStack/Search/SearchResult.cs @@ -14,7 +14,7 @@ public class SearchResult public long TotalResults { get; } public List Documents { get; } - internal SearchResult(RedisResult[] resp, bool hasContent, bool hasScores, bool hasPayloads, bool shouldExplainScore) + internal SearchResult(RedisResult[] resp, bool hasContent, bool hasScores, bool hasPayloads/*, bool shouldExplainScore*/) { // Calculate the step distance to walk over the results. // The order of results is id, score (if withScore), payLoad (if hasPayloads), fields @@ -53,17 +53,17 @@ internal SearchResult(RedisResult[] resp, bool hasContent, bool hasScores, bool string[] scoreExplained = null; if (hasScores) { - if (shouldExplainScore) - { - var scoreResult = (RedisResult[])resp[i + scoreOffset]; - score = (double) scoreResult[0]; - var redisResultsScoreExplained = (RedisResult[]) scoreResult[1]; - scoreExplained = FlatRedisResultArray(redisResultsScoreExplained).ToArray(); - } - else - { + // if (shouldExplainScore) + // { + // var scoreResult = (RedisResult[])resp[i + scoreOffset]; + // score = (double) scoreResult[0]; + // var redisResultsScoreExplained = (RedisResult[]) scoreResult[1]; + // scoreExplained = FlatRedisResultArray(redisResultsScoreExplained).ToArray(); + // } + //else + //{ score = (double)resp[i + scoreOffset]; - } + //} } if (hasPayloads) { diff --git a/tests/NRedisStack.Tests/Search/SearchTests.cs b/tests/NRedisStack.Tests/Search/SearchTests.cs index c2f40c64..a545200f 100644 --- a/tests/NRedisStack.Tests/Search/SearchTests.cs +++ b/tests/NRedisStack.Tests/Search/SearchTests.cs @@ -1623,8 +1623,7 @@ public void TestQueryCommandBuilder() .SetPayload("txt") .SetLanguage("English") .SetScorer("TFIDF") - .SetExplainScore() - .SetWithScores() + //.SetExplainScore() .SetWithPayloads() .SetSortBy("txt", true) .Limit(0, 10) @@ -1643,7 +1642,6 @@ public void TestQueryCommandBuilder() "VERBATIM", "NOSTOPWORDS", "WITHSCORES", - "EXPLAINSCORE", "WITHPAYLOADS", "LANGUAGE", "English", @@ -1706,6 +1704,20 @@ public void TestQueryCommandBuilder() Assert.Equal(0, res.Documents.Count()); } + [Fact] + public void TestQueryCommandBuilderScore() + { + // TODO: write better test for scores and payloads + IDatabase db = redisFixture.Redis.GetDatabase(); + db.Execute("FLUSHALL"); + var ft = db.FT(); + + db.Execute("JSON.SET", "doc:1", "$", "[{\"arr\": [1, 2, 3]}, {\"val\": \"hello\"}, {\"val\": \"world\"}]"); + db.Execute("FT.CREATE", "idx", "ON", "JSON", "PREFIX", "1", "doc:", "SCHEMA", "$..arr", "AS", "arr", "NUMERIC", "$..val", "AS", "val", "TEXT"); + var res = ft.Search("idx", new Query("*").ReturnFields("arr", "val").SetWithScores().SetPayload("arr")); + Assert.Equal(1, res.TotalResults); + } + [Fact] public void TestFieldsCommandBuilder() { From 4bf2f2bd206c4b95a711385820f9c3497436f4d4 Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Mon, 9 Jan 2023 18:18:12 +0200 Subject: [PATCH 14/27] Cover CuckooCommandBuilder --- .../CuckooFilter/CuckooTests.cs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/tests/NRedisStack.Tests/CuckooFilter/CuckooTests.cs b/tests/NRedisStack.Tests/CuckooFilter/CuckooTests.cs index e32be109..f0bf13d0 100644 --- a/tests/NRedisStack.Tests/CuckooFilter/CuckooTests.cs +++ b/tests/NRedisStack.Tests/CuckooFilter/CuckooTests.cs @@ -22,7 +22,7 @@ public void TestReserveBasic() IDatabase db = redisFixture.Redis.GetDatabase(); db.Execute("FLUSHALL"); var cf = db.CF(); - Assert.True(cf.Reserve(key, 100L)); + Assert.True(cf.Reserve(key, 100L, maxIterations: 20, expansion: 1)); Assert.Throws(() => cf.Reserve(key, 100L)); Assert.True((cf.Add(key, "item1"))); @@ -36,7 +36,7 @@ public async Task TestReserveBasicAsync() IDatabase db = redisFixture.Redis.GetDatabase(); db.Execute("FLUSHALL"); var cf = db.CF(); - Assert.True(await cf.ReserveAsync(key, 100L)); + Assert.True(await cf.ReserveAsync(key, 100L, maxIterations: 20, expansion: 1)); Assert.ThrowsAsync(async () => await cf.ReserveAsync(key, 100L)); Assert.True(await (cf.AddAsync(key, "item1"))); @@ -271,7 +271,9 @@ public void TestInsertNX() RedisValue[] items = new RedisValue[] { "item1", "item2", "item3" }; - var result = cf.InsertNX(key, items); + Assert.Throws(() => cf.InsertNX(key, items, 1024, true)); + var result = cf.InsertNX(key, items, 1024); + cf.InsertNX(key, items, 10245, true); var trues = new bool[] { true, true, true }; Assert.Equal(result, trues); @@ -283,6 +285,9 @@ public void TestInsertNX() result = cf.InsertNX(key, items); Assert.Equal(result, new bool[] { false, false, false }); + + // test empty items: + Assert.Throws(() => cf.InsertNX(key, new RedisValue[]{})); } [Fact] @@ -294,7 +299,9 @@ public async Task TestInsertNXAsync() RedisValue[] items = new RedisValue[] { "item1", "item2", "item3" }; - var result = await cf.InsertNXAsync(key, items); + Assert.ThrowsAsync(async () => await cf.InsertNXAsync(key, items, 1024, true)); + var result = await cf.InsertNXAsync(key, items, 1024); + await cf.InsertNXAsync(key, items, 10245, true); var trues = new bool[] { true, true, true }; Assert.Equal(result, trues); @@ -306,6 +313,9 @@ public async Task TestInsertNXAsync() result = await cf.InsertNXAsync(key, items); Assert.Equal(result, new bool[] { false, false, false }); + + // test empty items: + Assert.ThrowsAsync(async () => await cf.InsertNXAsync(key, new RedisValue[]{})); } [Fact] From 65675f588721fe821db5f8be3bb06f8a597da124 Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Tue, 10 Jan 2023 11:46:57 +0200 Subject: [PATCH 15/27] Cover TopK --- src/NRedisStack/Search/SearchResult.cs | 31 +++++++++++----------- src/NRedisStack/TopK/TopKCommandBuilder.cs | 5 ---- tests/NRedisStack.Tests/TopK/TopKTests.cs | 2 ++ 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/NRedisStack/Search/SearchResult.cs b/src/NRedisStack/Search/SearchResult.cs index 029f1533..15b20a96 100644 --- a/src/NRedisStack/Search/SearchResult.cs +++ b/src/NRedisStack/Search/SearchResult.cs @@ -79,20 +79,21 @@ internal SearchResult(RedisResult[] resp, bool hasContent, bool hasScores, bool } } - static IEnumerable FlatRedisResultArray(RedisResult[] collection) - { - foreach (var o in collection) - { - if (o.Type == ResultType.MultiBulk) - { - foreach (string t in FlatRedisResultArray((RedisResult[])o)) - yield return t; - } - else - { - yield return o.ToString(); - } - } - } + // TODO: Check if this is needed: + // static IEnumerable FlatRedisResultArray(RedisResult[] collection) + // { + // foreach (var o in collection) + // { + // if (o.Type == ResultType.MultiBulk) + // { + // foreach (string t in FlatRedisResultArray((RedisResult[])o)) + // yield return t; + // } + // else + // { + // yield return o.ToString(); + // } + // } + // } } } \ No newline at end of file diff --git a/src/NRedisStack/TopK/TopKCommandBuilder.cs b/src/NRedisStack/TopK/TopKCommandBuilder.cs index 8360899c..7e299054 100644 --- a/src/NRedisStack/TopK/TopKCommandBuilder.cs +++ b/src/NRedisStack/TopK/TopKCommandBuilder.cs @@ -49,11 +49,6 @@ public static SerializedCommand List(RedisKey key, bool withcount = false) : new SerializedCommand(TOPK.LIST, key); } - public static SerializedCommand Query(RedisKey key, RedisValue item) - { - return new SerializedCommand(TOPK.QUERY, key, item); - } - public static SerializedCommand Query(RedisKey key, params RedisValue[] items) { if (items.Length < 1) diff --git a/tests/NRedisStack.Tests/TopK/TopKTests.cs b/tests/NRedisStack.Tests/TopK/TopKTests.cs index 653e4175..478732ee 100644 --- a/tests/NRedisStack.Tests/TopK/TopKTests.cs +++ b/tests/NRedisStack.Tests/TopK/TopKTests.cs @@ -29,6 +29,7 @@ public void CreateTopKFilter() Assert.True(res[0].IsNull && res[1].IsNull); Assert.Equal(topk.Query("aaa", "bb", "gg", "cc"), new bool[] { true, false, true }); + Assert.False(topk.Query("aaa", "notExists")); Assert.Equal(topk.Count("aaa", "bb", "gg", "cc"), new long[] { 1, 0, 1 }); @@ -65,6 +66,7 @@ public async Task CreateTopKFilterAsync() Assert.True(res[0].IsNull && res[1].IsNull); Assert.Equal(await topk.QueryAsync("aaa", "bb", "gg", "cc"), new bool[] { true, false, true }); + Assert.False(await topk.QueryAsync("aaa", "notExists")); Assert.Equal(await topk.CountAsync("aaa", "bb", "gg", "cc"), new long[] { 1, 0, 1 }); From 9c3fb0ebe063d7ae875e25cecf9080cd969de8c5 Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Tue, 10 Jan 2023 12:05:21 +0200 Subject: [PATCH 16/27] Cover Search Query --- tests/NRedisStack.Tests/Search/SearchTests.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/NRedisStack.Tests/Search/SearchTests.cs b/tests/NRedisStack.Tests/Search/SearchTests.cs index a545200f..bd95e8e5 100644 --- a/tests/NRedisStack.Tests/Search/SearchTests.cs +++ b/tests/NRedisStack.Tests/Search/SearchTests.cs @@ -1629,6 +1629,8 @@ public void TestQueryCommandBuilder() .Limit(0, 10) .SummarizeFields(20, 3, ";", "txt") .LimitKeys("key1", "key2") + .LimitFields("txt") + .ReturnFields(new FieldName("txt")) .ReturnFields("txt") .AddParam("name", "value") .Dialect(1) @@ -1647,6 +1649,9 @@ public void TestQueryCommandBuilder() "English", "SCORER", "TFIDF", + "INFIELDS", + "1", + "txt", "SORTBY", "txt", "ASC", From 6bf5c8985d96ada5ad7e03f6ffcf1369862cb941 Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Tue, 10 Jan 2023 12:40:32 +0200 Subject: [PATCH 17/27] Cover All search Query --- tests/NRedisStack.Tests/Search/SearchTests.cs | 41 ++++++++++++++++++- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/tests/NRedisStack.Tests/Search/SearchTests.cs b/tests/NRedisStack.Tests/Search/SearchTests.cs index bd95e8e5..cc59d53d 100644 --- a/tests/NRedisStack.Tests/Search/SearchTests.cs +++ b/tests/NRedisStack.Tests/Search/SearchTests.cs @@ -1626,11 +1626,10 @@ public void TestQueryCommandBuilder() //.SetExplainScore() .SetWithPayloads() .SetSortBy("txt", true) - .Limit(0, 10) + .Limit(0, 11) .SummarizeFields(20, 3, ";", "txt") .LimitKeys("key1", "key2") .LimitFields("txt") - .ReturnFields(new FieldName("txt")) .ReturnFields("txt") .AddParam("name", "value") .Dialect(1) @@ -1657,6 +1656,9 @@ public void TestQueryCommandBuilder() "ASC", "PAYLOAD", "txt", + "LIMIT", + "0", + "11", "HIGHLIGHT", "FIELDS", "1", @@ -1709,6 +1711,41 @@ public void TestQueryCommandBuilder() Assert.Equal(0, res.Documents.Count()); } + [Fact] + public void TestQueryCommandBuilderReturnField() + { + var testQuery = new Query("foo").HighlightFields("txt") + .ReturnFields(new FieldName("txt")) + .SetNoContent(); + + + var buildCommand = SearchCommandBuilder.Search("idx", testQuery); + var expectedArgs = new List {"idx", + "foo", + "NOCONTENT", + "HIGHLIGHT", + "FIELDS", + "1", + "txt", + "RETURN", + "1", + "txt"}; + + for (int i = 0; i < buildCommand.Args.Count(); i++) + { + Assert.Equal(expectedArgs[i].ToString(), buildCommand.Args[i].ToString()); + } + Assert.Equal("FT.SEARCH", buildCommand.Command); + + // test that the command not throw an exception: + var db = redisFixture.Redis.GetDatabase(); + db.Execute("FLUSHALL"); + var ft = db.FT(); + ft.Create("idx", new FTCreateParams(), new Schema().AddTextField("txt")); + var res = ft.Search("idx", testQuery); + Assert.Equal(0, res.Documents.Count()); + } + [Fact] public void TestQueryCommandBuilderScore() { From d873cc080df6838139eac2a60b113d40bcf47347 Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Tue, 10 Jan 2023 12:50:31 +0200 Subject: [PATCH 18/27] Cover search schema --- tests/NRedisStack.Tests/Search/SearchTests.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/NRedisStack.Tests/Search/SearchTests.cs b/tests/NRedisStack.Tests/Search/SearchTests.cs index cc59d53d..e36806bb 100644 --- a/tests/NRedisStack.Tests/Search/SearchTests.cs +++ b/tests/NRedisStack.Tests/Search/SearchTests.cs @@ -1768,10 +1768,10 @@ public void TestFieldsCommandBuilder() var ft = db.FT(); // Create the index with the same fields as in the original test var sc = new Schema() - .AddTextField("txt", 1.0, true, true, true, "dm:en", true, true) - .AddNumericField("num", true, true) - .AddGeoField("loc", true, true) - .AddTagField("tag", true, true, true, ";", true, true) + .AddTextField(FieldName.Of("txt"), 1.0, true, true, true, "dm:en", true, true) + .AddNumericField(FieldName.Of("num"), true, true) + .AddGeoField(FieldName.Of("loc"), true, true) + .AddTagField(FieldName.Of("tag"), true, true, true, ";", true, true) .AddVectorField("vec", VectorField.VectorAlgo.FLAT, null); var buildCommand = SearchCommandBuilder.Create("idx", new FTCreateParams(), sc); var expectedArgs = new List { From 2c1edc279936bc606fae3781ffecb958804d3708 Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Tue, 10 Jan 2023 12:57:44 +0200 Subject: [PATCH 19/27] Cover FT._List --- tests/NRedisStack.Tests/Search/SearchTests.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/NRedisStack.Tests/Search/SearchTests.cs b/tests/NRedisStack.Tests/Search/SearchTests.cs index e36806bb..67013858 100644 --- a/tests/NRedisStack.Tests/Search/SearchTests.cs +++ b/tests/NRedisStack.Tests/Search/SearchTests.cs @@ -1855,6 +1855,24 @@ public async Task TestLimitAsync() Assert.Equal( res.GetResults()[0]["t1"].ToString(), "b"); } + [Fact] + public void Test_List() + { + IDatabase db = redisFixture.Redis.GetDatabase(); + db.Execute("FLUSHALL"); + var ft = db.FT(); + Assert.Equal(ft._List(), new RedisResult[] { }); + } + + [Fact] + public async Task Test_ListAsync() + { + IDatabase db = redisFixture.Redis.GetDatabase(); + db.Execute("FLUSHALL"); + var ft = db.FT(); + Assert.Equal(await ft._ListAsync(), new RedisResult[] { }); + } + [Fact] public void TestModulePrefixs1() { From b10875255d83e0791e1599125780dc6dde403d20 Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Tue, 10 Jan 2023 15:24:14 +0200 Subject: [PATCH 20/27] mark as Comment CallProcedureReadOnly --- src/NRedisStack/Graph/GraphCacheList.cs | 19 +++++----- src/NRedisStack/Graph/GraphCommands.cs | 36 +++++++++---------- src/NRedisStack/Graph/IGraphCommands.cs | 48 ++++++++++++------------- 3 files changed, 52 insertions(+), 51 deletions(-) diff --git a/src/NRedisStack/Graph/GraphCacheList.cs b/src/NRedisStack/Graph/GraphCacheList.cs index 74db8abe..a6000b55 100644 --- a/src/NRedisStack/Graph/GraphCacheList.cs +++ b/src/NRedisStack/Graph/GraphCacheList.cs @@ -53,14 +53,15 @@ protected virtual ResultSet CallProcedure() => graph.CallProcedure(GraphName, Procedure); } - internal class ReadOnlyGraphCacheList : GraphCacheList - { - internal ReadOnlyGraphCacheList(string graphName, string procedure, GraphCommands redisGraph) : - base(graphName, procedure, redisGraph) - { - } + // TODO: Check if this is needed: + // internal class ReadOnlyGraphCacheList : GraphCacheList + // { + // internal ReadOnlyGraphCacheList(string graphName, string procedure, GraphCommands redisGraph) : + // base(graphName, procedure, redisGraph) + // { + // } - protected override ResultSet CallProcedure() => - graph.CallProcedureReadOnly(GraphName, Procedure); - } + // protected override ResultSet CallProcedure() => + // graph.CallProcedureReadOnly(GraphName, Procedure); + // } } \ No newline at end of file diff --git a/src/NRedisStack/Graph/GraphCommands.cs b/src/NRedisStack/Graph/GraphCommands.cs index 3779b961..2a5d317d 100644 --- a/src/NRedisStack/Graph/GraphCommands.cs +++ b/src/NRedisStack/Graph/GraphCommands.cs @@ -148,30 +148,30 @@ public async Task DeleteAsync(string graphName) } // TODO: Check if this (CallProcedure) is needed - /// - public ResultSet CallProcedureReadOnly(string graphName, string procedure) => - CallProcedureReadOnly(graphName, procedure, Enumerable.Empty(), EmptyKwargsDictionary); + // /// + // public ResultSet CallProcedureReadOnly(string graphName, string procedure) => + // CallProcedureReadOnly(graphName, procedure, Enumerable.Empty(), EmptyKwargsDictionary); - /// - public ResultSet CallProcedureReadOnly(string graphName, string procedure, IEnumerable args) => - CallProcedureReadOnly(graphName, procedure, args, EmptyKwargsDictionary); + // /// + // public ResultSet CallProcedureReadOnly(string graphName, string procedure, IEnumerable args) => + // CallProcedureReadOnly(graphName, procedure, args, EmptyKwargsDictionary); - /// - public ResultSet CallProcedureReadOnly(string graphName, string procedure, IEnumerable args, Dictionary> kwargs) - { - args = args.Select(a => QuoteString(a)); + // /// + // public ResultSet CallProcedureReadOnly(string graphName, string procedure, IEnumerable args, Dictionary> kwargs) + // { + // args = args.Select(a => QuoteString(a)); - var queryBody = new StringBuilder(); + // var queryBody = new StringBuilder(); - queryBody.Append($"CALL {procedure}({string.Join(",", args)})"); + // queryBody.Append($"CALL {procedure}({string.Join(",", args)})"); - if (kwargs.TryGetValue("y", out var kwargsList)) - { - queryBody.Append(string.Join(",", kwargsList)); - } + // if (kwargs.TryGetValue("y", out var kwargsList)) + // { + // queryBody.Append(string.Join(",", kwargsList)); + // } - return RO_Query(graphName, queryBody.ToString()); - } + // return RO_Query(graphName, queryBody.ToString()); + // } /// public IReadOnlyList Explain(string graphName, string query) diff --git a/src/NRedisStack/Graph/IGraphCommands.cs b/src/NRedisStack/Graph/IGraphCommands.cs index cf374eb8..2f23d71f 100644 --- a/src/NRedisStack/Graph/IGraphCommands.cs +++ b/src/NRedisStack/Graph/IGraphCommands.cs @@ -134,32 +134,32 @@ public interface IGraphCommands Task DeleteAsync(string graphName); // TODO: Check if this (CallProcedure) is needed - /// - /// Call a saved procedure against a read-only node. - /// - /// The graph containing the saved procedure. - /// The procedure name. - /// A result set. - ResultSet CallProcedureReadOnly(string graphName, string procedure); + // /// + // /// Call a saved procedure against a read-only node. + // /// + // /// The graph containing the saved procedure. + // /// The procedure name. + // /// A result set. + // ResultSet CallProcedureReadOnly(string graphName, string procedure); - /// - /// Call a saved procedure with parameters against a read-only node. - /// - /// The graph containing the saved procedure. - /// The procedure name. - /// A collection of positional arguments. - /// A result set. - ResultSet CallProcedureReadOnly(string graphName, string procedure, IEnumerable args); + // /// + // /// Call a saved procedure with parameters against a read-only node. + // /// + // /// The graph containing the saved procedure. + // /// The procedure name. + // /// A collection of positional arguments. + // /// A result set. + // ResultSet CallProcedureReadOnly(string graphName, string procedure, IEnumerable args); - /// - /// Call a saved procedure with parameters against a read-only node. - /// - /// The graph containing the saved procedure. - /// The procedure name. - /// A collection of positional arguments. - /// A collection of keyword arguments. - /// A result set. - ResultSet CallProcedureReadOnly(string graphName, string procedure, IEnumerable args, Dictionary> kwargs); + // /// + // /// Call a saved procedure with parameters against a read-only node. + // /// + // /// The graph containing the saved procedure. + // /// The procedure name. + // /// A collection of positional arguments. + // /// A collection of keyword arguments. + // /// A result set. + // ResultSet CallProcedureReadOnly(string graphName, string procedure, IEnumerable args, Dictionary> kwargs); /// /// Constructs a query execution plan but does not run it. Inspect this execution plan to better understand how your From 6258bab1738de0bfa65c4660b944e4abf1650702 Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Tue, 10 Jan 2023 16:46:06 +0200 Subject: [PATCH 21/27] =?UTF-8?q?=D7=91=D7=9D=D7=A6=D7=A6=D7=A7=D7=9E?= =?UTF-8?q?=D7=90=20ValueToStringNoQuotes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/NRedisStack/Graph/RedisGraphUtilities.cs | 29 ++++++++++---------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/NRedisStack/Graph/RedisGraphUtilities.cs b/src/NRedisStack/Graph/RedisGraphUtilities.cs index 5f10cd74..ca5774e0 100644 --- a/src/NRedisStack/Graph/RedisGraphUtilities.cs +++ b/src/NRedisStack/Graph/RedisGraphUtilities.cs @@ -22,20 +22,21 @@ internal static string PrepareQuery(string query, IDictionary pa return preparedQuery.ToString(); } - public static string ValueToStringNoQuotes(object value) - { - if (value == null) - { - return "null"; - } - - if (value is IConvertible floatValue) - { - return ConvertibleToString(floatValue); - } - - return value.ToString(); - } + // TODO: Check if this is needed: + // public static string ValueToStringNoQuotes(object value) + // { + // if (value == null) + // { + // return "null"; + // } + + // if (value is IConvertible floatValue) + // { + // return ConvertibleToString(floatValue); + // } + + // return value.ToString(); + // } public static string ValueToString(object value) { From fdb4b10c8abc0a557df2086a03a37b61bcdd5ef5 Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Tue, 10 Jan 2023 17:46:20 +0200 Subject: [PATCH 22/27] cover more from AddVectorField --- tests/NRedisStack.Tests/Search/SearchTests.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/NRedisStack.Tests/Search/SearchTests.cs b/tests/NRedisStack.Tests/Search/SearchTests.cs index 67013858..4c47c012 100644 --- a/tests/NRedisStack.Tests/Search/SearchTests.cs +++ b/tests/NRedisStack.Tests/Search/SearchTests.cs @@ -1772,7 +1772,7 @@ public void TestFieldsCommandBuilder() .AddNumericField(FieldName.Of("num"), true, true) .AddGeoField(FieldName.Of("loc"), true, true) .AddTagField(FieldName.Of("tag"), true, true, true, ";", true, true) - .AddVectorField("vec", VectorField.VectorAlgo.FLAT, null); + .AddVectorField("vec", VectorField.VectorAlgo.FLAT, new Dictionary { { "dim", 10 } }); var buildCommand = SearchCommandBuilder.Create("idx", new FTCreateParams(), sc); var expectedArgs = new List { "idx", @@ -1805,7 +1805,10 @@ public void TestFieldsCommandBuilder() "CASESENSITIVE", "vec", "VECTOR", - "FLAT" + "FLAT", + "1", + "dim", + "10" }; Assert.Equal("FT.CREATE", buildCommand.Command); From 9062cf0245c41ed842afd1106af11fbb29354c02 Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Tue, 10 Jan 2023 18:08:27 +0200 Subject: [PATCH 23/27] More cover to timeSeries --- .../Extensions/AggregationExtensions.cs | 7 ++--- .../Extensions/BucketTimestampsExtensions.cs | 15 ++++----- tests/NRedisStack.Tests/Search/SearchTests.cs | 2 +- .../TimeSeries/TestAPI/TestRange.cs | 31 ++++++++++++++++--- .../TimeSeries/TestAPI/TestRangeAsync.cs | 31 ++++++++++++++++--- 5 files changed, 65 insertions(+), 21 deletions(-) diff --git a/src/NRedisStack/TimeSeries/Extensions/AggregationExtensions.cs b/src/NRedisStack/TimeSeries/Extensions/AggregationExtensions.cs index e718514d..2512ffb9 100644 --- a/src/NRedisStack/TimeSeries/Extensions/AggregationExtensions.cs +++ b/src/NRedisStack/TimeSeries/Extensions/AggregationExtensions.cs @@ -1,5 +1,4 @@ -using System; -using NRedisStack.Literals.Enums; +using NRedisStack.Literals.Enums; namespace NRedisStack.Extensions { @@ -25,7 +24,7 @@ internal static class AggregationExtensions public static TsAggregation AsAggregation(string aggregation) => aggregation switch { - "avg" => TsAggregation.Avg, + /*"avg" => TsAggregation.Avg, "sum" => TsAggregation.Sum, "min" => TsAggregation.Min, "max" => TsAggregation.Max, @@ -37,7 +36,7 @@ internal static class AggregationExtensions "std.s" => TsAggregation.StdS, "var.p" => TsAggregation.VarP, "var.s" => TsAggregation.VarS, - "twa" => TsAggregation.Twa, + "twa" => TsAggregation.Twa,*/ "AVG" => TsAggregation.Avg, "SUM" => TsAggregation.Sum, "MIN" => TsAggregation.Min, diff --git a/src/NRedisStack/TimeSeries/Extensions/BucketTimestampsExtensions.cs b/src/NRedisStack/TimeSeries/Extensions/BucketTimestampsExtensions.cs index cb945039..bdca2a5a 100644 --- a/src/NRedisStack/TimeSeries/Extensions/BucketTimestampsExtensions.cs +++ b/src/NRedisStack/TimeSeries/Extensions/BucketTimestampsExtensions.cs @@ -13,12 +13,13 @@ internal static class TsBucketTimestampsExtensions _ => throw new ArgumentOutOfRangeException(nameof(bt), "Invalid TsBucketTimestamps type"), }; - public static TsBucketTimestamps Asbt(string bt) => bt switch - { - "-" => TsBucketTimestamps.low, - "~" => TsBucketTimestamps.mid, - "+" => TsBucketTimestamps.high, - _ => throw new ArgumentOutOfRangeException(nameof(bt), $"Invalid TsBucketTimestamps type '{bt}'"), - }; + // TODO: check if this is needed: + // public static TsBucketTimestamps Asbt(string bt) => bt switch + // { + // "-" => TsBucketTimestamps.low, + // "~" => TsBucketTimestamps.mid, + // "+" => TsBucketTimestamps.high, + // _ => throw new ArgumentOutOfRangeException(nameof(bt), $"Invalid TsBucketTimestamps type '{bt}'"), + // }; } } \ No newline at end of file diff --git a/tests/NRedisStack.Tests/Search/SearchTests.cs b/tests/NRedisStack.Tests/Search/SearchTests.cs index 4c47c012..fcdf95f8 100644 --- a/tests/NRedisStack.Tests/Search/SearchTests.cs +++ b/tests/NRedisStack.Tests/Search/SearchTests.cs @@ -1814,7 +1814,7 @@ public void TestFieldsCommandBuilder() Assert.Equal("FT.CREATE", buildCommand.Command); for (int i = 0; i < expectedArgs.Count; i++) { - Assert.Equal(expectedArgs[i], buildCommand.Args[i]); + Assert.Equal(expectedArgs[i], buildCommand.Args[i].ToString()); } } diff --git a/tests/NRedisStack.Tests/TimeSeries/TestAPI/TestRange.cs b/tests/NRedisStack.Tests/TimeSeries/TestAPI/TestRange.cs index eb3599b3..f21370ac 100644 --- a/tests/NRedisStack.Tests/TimeSeries/TestAPI/TestRange.cs +++ b/tests/NRedisStack.Tests/TimeSeries/TestAPI/TestRange.cs @@ -200,7 +200,7 @@ public void TestBucketTimestamp() ts.Add("t1", 73, 5); ts.Add("t1", 75, 3); - var range = ts.Range("t1", 0, 100, + var rangeHigh = ts.Range("t1", 0, 100, align: 0, aggregation: TsAggregation.Max, timeBucket: 10); @@ -209,19 +209,40 @@ public void TestBucketTimestamp() expected.Add(new TimeSeriesTuple(10, 4.0)); expected.Add(new TimeSeriesTuple(50, 3.0)); expected.Add(new TimeSeriesTuple(70, 5.0)); - Assert.Equal(range, expected); + Assert.Equal(rangeHigh, expected); - range = ts.Range("t1", 0, 100, + rangeHigh = ts.Range("t1", 0, 100, align: 0, aggregation: TsAggregation.Max, timeBucket: 10, bt: TsBucketTimestamps.high); - expected.Clear(); expected.Add(new TimeSeriesTuple(20, 4.0)); expected.Add(new TimeSeriesTuple(60, 3.0)); expected.Add(new TimeSeriesTuple(80, 5.0)); - Assert.Equal(range, expected); + Assert.Equal(rangeHigh, expected); + + var rangeLow = ts.Range("t1", 0, 100, + align: 0, + aggregation: TsAggregation.Max, + timeBucket: 10, + bt: TsBucketTimestamps.low); + expected.Clear(); + expected.Add(new TimeSeriesTuple(10, 4.0)); + expected.Add(new TimeSeriesTuple(50, 3.0)); + expected.Add(new TimeSeriesTuple(70, 5.0)); + Assert.Equal(rangeLow, expected); + + var rangeMid = ts.Range("t1", 0, 100, + align: 0, + aggregation: TsAggregation.Max, + timeBucket: 10, + bt: TsBucketTimestamps.mid); + expected.Clear(); + expected.Add(new TimeSeriesTuple(15, 4.0)); + expected.Add(new TimeSeriesTuple(55, 3.0)); + expected.Add(new TimeSeriesTuple(75, 5.0)); + Assert.Equal(rangeMid, expected); } [Fact] diff --git a/tests/NRedisStack.Tests/TimeSeries/TestAPI/TestRangeAsync.cs b/tests/NRedisStack.Tests/TimeSeries/TestAPI/TestRangeAsync.cs index 5de3d01a..381aac78 100644 --- a/tests/NRedisStack.Tests/TimeSeries/TestAPI/TestRangeAsync.cs +++ b/tests/NRedisStack.Tests/TimeSeries/TestAPI/TestRangeAsync.cs @@ -200,7 +200,7 @@ public async Task TestBucketTimestampAsync() ts.Add("t1", 73, 5); ts.Add("t1", 75, 3); - var range = await ts.RangeAsync("t1", 0, 100, + var rangeHigh = await ts.RangeAsync("t1", 0, 100, align: 0, aggregation: TsAggregation.Max, timeBucket: 10); @@ -209,9 +209,9 @@ public async Task TestBucketTimestampAsync() expected.Add(new TimeSeriesTuple(10, 4.0)); expected.Add(new TimeSeriesTuple(50, 3.0)); expected.Add(new TimeSeriesTuple(70, 5.0)); - Assert.Equal(range, expected); + Assert.Equal(rangeHigh, expected); - range = await ts.RangeAsync("t1", 0, 100, + rangeHigh = await ts.RangeAsync("t1", 0, 100, align: 0, aggregation: TsAggregation.Max, timeBucket: 10, @@ -221,7 +221,30 @@ public async Task TestBucketTimestampAsync() expected.Add(new TimeSeriesTuple(20, 4.0)); expected.Add(new TimeSeriesTuple(60, 3.0)); expected.Add(new TimeSeriesTuple(80, 5.0)); - Assert.Equal(range, expected); + Assert.Equal(rangeHigh, expected); + + var rangeLow = await ts.RangeAsync("t1", 0, 100, + align: 0, + aggregation: TsAggregation.Max, + timeBucket: 10, + bt: TsBucketTimestamps.low); + expected.Clear(); + expected.Add(new TimeSeriesTuple(10, 4.0)); + expected.Add(new TimeSeriesTuple(50, 3.0)); + expected.Add(new TimeSeriesTuple(70, 5.0)); + Assert.Equal(rangeLow, expected); + + var rangeMid = await ts.RangeAsync("t1", 0, 100, + align: 0, + aggregation: TsAggregation.Max, + timeBucket: 10, + bt: TsBucketTimestamps.mid); + expected.Clear(); + expected.Add(new TimeSeriesTuple(15, 4.0)); + expected.Add(new TimeSeriesTuple(55, 3.0)); + expected.Add(new TimeSeriesTuple(75, 5.0)); + Assert.Equal(rangeMid, expected); + } [Fact] From 8d019d3809e51ed3c446367b266d15eb991aa330 Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Tue, 10 Jan 2023 18:15:59 +0200 Subject: [PATCH 24/27] Comment TsDuplicatePolicy AsPolicy --- .../TimeSeries/Extensions/ReduceExtensions.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/NRedisStack/TimeSeries/Extensions/ReduceExtensions.cs b/src/NRedisStack/TimeSeries/Extensions/ReduceExtensions.cs index 005920c0..e79ab37f 100644 --- a/src/NRedisStack/TimeSeries/Extensions/ReduceExtensions.cs +++ b/src/NRedisStack/TimeSeries/Extensions/ReduceExtensions.cs @@ -13,12 +13,13 @@ internal static class ReduceExtensions _ => throw new ArgumentOutOfRangeException(nameof(reduce), "Invalid Reduce type"), }; - public static TsReduce AsReduce(string reduce) => reduce switch - { - "SUM" => TsReduce.Sum, - "MIN" => TsReduce.Min, - "MAX" => TsReduce.Max, - _ => throw new ArgumentOutOfRangeException(nameof(reduce), $"Invalid Reduce type '{reduce}'"), - }; + // TODO: check if this is needed: + // public static TsReduce AsReduce(string reduce) => reduce switch + // { + // "SUM" => TsReduce.Sum, + // "MIN" => TsReduce.Min, + // "MAX" => TsReduce.Max, + // _ => throw new ArgumentOutOfRangeException(nameof(reduce), $"Invalid Reduce type '{reduce}'"), + // }; } } From 6e5caf80915b3561d237d7add2e31268bef26fdf Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Wed, 11 Jan 2023 16:55:13 +0200 Subject: [PATCH 25/27] delete unnecessary code from graph --- src/NRedisStack/Graph/DataTypes/Edge.cs | 1 - .../Graph/DataTypes/GraphEntity.cs | 21 +------------- src/NRedisStack/Graph/DataTypes/Node.cs | 1 - src/NRedisStack/Graph/DataTypes/Path.cs | 2 -- src/NRedisStack/Graph/GraphCacheList.cs | 12 -------- src/NRedisStack/Graph/GraphCommands.cs | 28 +------------------ src/NRedisStack/Graph/Header.cs | 3 +- src/NRedisStack/Graph/IGraphCommands.cs | 28 ------------------- src/NRedisStack/Graph/Point.cs | 1 - src/NRedisStack/Graph/Record.cs | 1 - src/NRedisStack/Graph/RedisGraphUtilities.cs | 16 ----------- src/NRedisStack/Json/JsonCommandBuilder.cs | 2 +- src/NRedisStack/Json/JsonCommands.cs | 3 -- .../TimeSeries/Extensions/ReduceExtensions.cs | 9 ------ 14 files changed, 4 insertions(+), 124 deletions(-) diff --git a/src/NRedisStack/Graph/DataTypes/Edge.cs b/src/NRedisStack/Graph/DataTypes/Edge.cs index 3e446f22..24e7df5b 100644 --- a/src/NRedisStack/Graph/DataTypes/Edge.cs +++ b/src/NRedisStack/Graph/DataTypes/Edge.cs @@ -26,7 +26,6 @@ public class Edge : GraphEntity /// public long Destination { get; set; } - // TODO: check if this is needed: /// /// Overriden from the base `Equals` implementation. In addition to the expected behavior of checking /// reference equality, we'll also fall back and check to see if the: Source, Destination, and RelationshipType diff --git a/src/NRedisStack/Graph/DataTypes/GraphEntity.cs b/src/NRedisStack/Graph/DataTypes/GraphEntity.cs index 46383db6..6e3401c9 100644 --- a/src/NRedisStack/Graph/DataTypes/GraphEntity.cs +++ b/src/NRedisStack/Graph/DataTypes/GraphEntity.cs @@ -12,7 +12,6 @@ public abstract class GraphEntity public IDictionary PropertyMap = new Dictionary(); - // TODO: check if this is needed: /// /// Overriden Equals that considers the equality of the entity ID as well as the equality of the /// properties that each entity has. @@ -49,7 +48,7 @@ public override int GetHashCode() hash = hash * 31 + Id.GetHashCode(); - foreach(var prop in PropertyMap) + foreach (var prop in PropertyMap) { hash = hash * 31 + prop.Key.GetHashCode(); hash = hash * 31 + prop.Value.GetHashCode(); @@ -59,24 +58,6 @@ public override int GetHashCode() } } - // TODO: Delete it? - /// - /// Overriden ToString that emits a string containing the ID and property map of the entity. - /// - /// - // public override string ToString() - // { - // var sb = new StringBuilder(); - - // sb.Append("GraphEntity{id="); - // sb.Append(Id); - // sb.Append(", propertyMap="); - // sb.Append(PropertyMap); - // sb.Append('}'); - - // return sb.ToString(); - // } - public string PropertyMapToString() { var sb = new StringBuilder(); diff --git a/src/NRedisStack/Graph/DataTypes/Node.cs b/src/NRedisStack/Graph/DataTypes/Node.cs index 92fda49b..05a30e86 100644 --- a/src/NRedisStack/Graph/DataTypes/Node.cs +++ b/src/NRedisStack/Graph/DataTypes/Node.cs @@ -16,7 +16,6 @@ public Node() Labels = new List(); } - // TODO: check if this is needed: /// /// Overriden member that checks to see if the names of the labels of a node are equal /// (in addition to base `Equals` functionality). diff --git a/src/NRedisStack/Graph/DataTypes/Path.cs b/src/NRedisStack/Graph/DataTypes/Path.cs index 0efa1dde..02af0c8e 100644 --- a/src/NRedisStack/Graph/DataTypes/Path.cs +++ b/src/NRedisStack/Graph/DataTypes/Path.cs @@ -20,7 +20,6 @@ public Path(IList nodes, IList edges) Edges = new ReadOnlyCollection(edges); } - // TODO: check if this is needed: /// /// Overriden `Equals` method that will consider the equality of the Nodes and Edges between two paths. /// @@ -68,7 +67,6 @@ public override int GetHashCode() } } - // TODO: check if this is needed: /// /// Overridden `ToString` method that will emit a string based on the string values of the nodes and edges /// on the path. diff --git a/src/NRedisStack/Graph/GraphCacheList.cs b/src/NRedisStack/Graph/GraphCacheList.cs index a6000b55..b6e16d92 100644 --- a/src/NRedisStack/Graph/GraphCacheList.cs +++ b/src/NRedisStack/Graph/GraphCacheList.cs @@ -52,16 +52,4 @@ private void GetProcedureInfo() protected virtual ResultSet CallProcedure() => graph.CallProcedure(GraphName, Procedure); } - - // TODO: Check if this is needed: - // internal class ReadOnlyGraphCacheList : GraphCacheList - // { - // internal ReadOnlyGraphCacheList(string graphName, string procedure, GraphCommands redisGraph) : - // base(graphName, procedure, redisGraph) - // { - // } - - // protected override ResultSet CallProcedure() => - // graph.CallProcedureReadOnly(GraphName, Procedure); - // } } \ No newline at end of file diff --git a/src/NRedisStack/Graph/GraphCommands.cs b/src/NRedisStack/Graph/GraphCommands.cs index 2a5d317d..a1363f6b 100644 --- a/src/NRedisStack/Graph/GraphCommands.cs +++ b/src/NRedisStack/Graph/GraphCommands.cs @@ -97,7 +97,7 @@ public async Task RO_QueryAsync(string graphName, string query, long? internal static readonly Dictionary> EmptyKwargsDictionary = new Dictionary>(); - // TODO: Check if needed + // TODO: Check if this is needed: /// public ResultSet CallProcedure(string graphName, string procedure) => CallProcedure(graphName, procedure, Enumerable.Empty(), EmptyKwargsDictionary); @@ -147,32 +147,6 @@ public async Task DeleteAsync(string graphName) return processedResult; } - // TODO: Check if this (CallProcedure) is needed - // /// - // public ResultSet CallProcedureReadOnly(string graphName, string procedure) => - // CallProcedureReadOnly(graphName, procedure, Enumerable.Empty(), EmptyKwargsDictionary); - - // /// - // public ResultSet CallProcedureReadOnly(string graphName, string procedure, IEnumerable args) => - // CallProcedureReadOnly(graphName, procedure, args, EmptyKwargsDictionary); - - // /// - // public ResultSet CallProcedureReadOnly(string graphName, string procedure, IEnumerable args, Dictionary> kwargs) - // { - // args = args.Select(a => QuoteString(a)); - - // var queryBody = new StringBuilder(); - - // queryBody.Append($"CALL {procedure}({string.Join(",", args)})"); - - // if (kwargs.TryGetValue("y", out var kwargsList)) - // { - // queryBody.Append(string.Join(",", kwargsList)); - // } - - // return RO_Query(graphName, queryBody.ToString()); - // } - /// public IReadOnlyList Explain(string graphName, string query) { diff --git a/src/NRedisStack/Graph/Header.cs b/src/NRedisStack/Graph/Header.cs index ea9a6259..3101986c 100644 --- a/src/NRedisStack/Graph/Header.cs +++ b/src/NRedisStack/Graph/Header.cs @@ -20,7 +20,7 @@ public enum ResultSetColumnTypes /// /// Collection of the schema types present in the header. /// - // [Obsolete("SchemaType is no longer supported after RedisGraph 2.1 and will always return COLUMN_SCALAR")] // TODO: it's correct? + [Obsolete("SchemaType is no longer supported after RedisGraph 2.1 and will always return COLUMN_SCALAR")] public List SchemaTypes { get; } /// @@ -41,7 +41,6 @@ internal Header(RedisResult result) } } - // TODO: check if this is needed: public override bool Equals(object? obj) { if (obj == null) return this == null; diff --git a/src/NRedisStack/Graph/IGraphCommands.cs b/src/NRedisStack/Graph/IGraphCommands.cs index 2f23d71f..e2470b64 100644 --- a/src/NRedisStack/Graph/IGraphCommands.cs +++ b/src/NRedisStack/Graph/IGraphCommands.cs @@ -133,34 +133,6 @@ public interface IGraphCommands /// Task DeleteAsync(string graphName); - // TODO: Check if this (CallProcedure) is needed - // /// - // /// Call a saved procedure against a read-only node. - // /// - // /// The graph containing the saved procedure. - // /// The procedure name. - // /// A result set. - // ResultSet CallProcedureReadOnly(string graphName, string procedure); - - // /// - // /// Call a saved procedure with parameters against a read-only node. - // /// - // /// The graph containing the saved procedure. - // /// The procedure name. - // /// A collection of positional arguments. - // /// A result set. - // ResultSet CallProcedureReadOnly(string graphName, string procedure, IEnumerable args); - - // /// - // /// Call a saved procedure with parameters against a read-only node. - // /// - // /// The graph containing the saved procedure. - // /// The procedure name. - // /// A collection of positional arguments. - // /// A collection of keyword arguments. - // /// A result set. - // ResultSet CallProcedureReadOnly(string graphName, string procedure, IEnumerable args, Dictionary> kwargs); - /// /// Constructs a query execution plan but does not run it. Inspect this execution plan to better understand how your /// query will get executed. diff --git a/src/NRedisStack/Graph/Point.cs b/src/NRedisStack/Graph/Point.cs index a1f9a226..4bb562fb 100644 --- a/src/NRedisStack/Graph/Point.cs +++ b/src/NRedisStack/Graph/Point.cs @@ -23,7 +23,6 @@ public Point(List values) this.longitude = values[1]; } - // TODO: check if this is needed: public override bool Equals(object? obj) { if (obj == null) return this == null; diff --git a/src/NRedisStack/Graph/Record.cs b/src/NRedisStack/Graph/Record.cs index 84a9346c..be2346ec 100644 --- a/src/NRedisStack/Graph/Record.cs +++ b/src/NRedisStack/Graph/Record.cs @@ -58,7 +58,6 @@ internal Record(List header, List values) /// public int Size => Header.Count; - // TODO: check if this is needed: public override bool Equals(object? obj) { if (obj == null) return this == null; diff --git a/src/NRedisStack/Graph/RedisGraphUtilities.cs b/src/NRedisStack/Graph/RedisGraphUtilities.cs index ca5774e0..a13f1049 100644 --- a/src/NRedisStack/Graph/RedisGraphUtilities.cs +++ b/src/NRedisStack/Graph/RedisGraphUtilities.cs @@ -22,22 +22,6 @@ internal static string PrepareQuery(string query, IDictionary pa return preparedQuery.ToString(); } - // TODO: Check if this is needed: - // public static string ValueToStringNoQuotes(object value) - // { - // if (value == null) - // { - // return "null"; - // } - - // if (value is IConvertible floatValue) - // { - // return ConvertibleToString(floatValue); - // } - - // return value.ToString(); - // } - public static string ValueToString(object value) { if (value == null) diff --git a/src/NRedisStack/Json/JsonCommandBuilder.cs b/src/NRedisStack/Json/JsonCommandBuilder.cs index 3f06ede9..4924a346 100644 --- a/src/NRedisStack/Json/JsonCommandBuilder.cs +++ b/src/NRedisStack/Json/JsonCommandBuilder.cs @@ -113,7 +113,7 @@ public static SerializedCommand ArrPop(RedisKey key, string? path = null, long? throw new ArgumentException("index cannot be defined without path"); var args = AssembleNonNullArguments(key, path, index); - return new SerializedCommand(JSON.ARRPOP, args)!; // TODO: understand the meaning of the '!' here + return new SerializedCommand(JSON.ARRPOP, args)!; } public static SerializedCommand ArrTrim(RedisKey key, string path, long start, long stop) => diff --git a/src/NRedisStack/Json/JsonCommands.cs b/src/NRedisStack/Json/JsonCommands.cs index 8c2a2116..a1ec708f 100644 --- a/src/NRedisStack/Json/JsonCommands.cs +++ b/src/NRedisStack/Json/JsonCommands.cs @@ -250,7 +250,6 @@ public async Task SetAsync(RedisKey key, RedisValue path, RedisValue json, return (await _db.ExecuteAsync(JsonCommandBuilder.Set(key, path, json, when))).OKtoBoolean(); } - /// // TODO: check way asnyc methods dont have documenation public async Task SetFromFileAsync(RedisKey key, RedisValue path, string filePath, When when = When.Always) { if (!File.Exists(filePath)) @@ -262,7 +261,6 @@ public async Task SetFromFileAsync(RedisKey key, RedisValue path, string f return await SetAsync(key, path, fileContent, when); } - /// public async Task SetFromDirectoryAsync(RedisValue path, string filesPath, When when = When.Always) { int inserted = 0; @@ -285,7 +283,6 @@ public async Task SetFromDirectoryAsync(RedisValue path, string filesPath, return inserted; } - public async Task StrAppendAsync(RedisKey key, string value, string? path = null) { return (await _db.ExecuteAsync(JsonCommandBuilder.StrAppend(key, value, path))).ToNullableLongArray(); diff --git a/src/NRedisStack/TimeSeries/Extensions/ReduceExtensions.cs b/src/NRedisStack/TimeSeries/Extensions/ReduceExtensions.cs index e79ab37f..2485e2a6 100644 --- a/src/NRedisStack/TimeSeries/Extensions/ReduceExtensions.cs +++ b/src/NRedisStack/TimeSeries/Extensions/ReduceExtensions.cs @@ -12,14 +12,5 @@ internal static class ReduceExtensions TsReduce.Max => "MAX", _ => throw new ArgumentOutOfRangeException(nameof(reduce), "Invalid Reduce type"), }; - - // TODO: check if this is needed: - // public static TsReduce AsReduce(string reduce) => reduce switch - // { - // "SUM" => TsReduce.Sum, - // "MIN" => TsReduce.Min, - // "MAX" => TsReduce.Max, - // _ => throw new ArgumentOutOfRangeException(nameof(reduce), $"Invalid Reduce type '{reduce}'"), - // }; } } From 71734a0a0929ac87aa2197e729c316f57328dc62 Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Wed, 11 Jan 2023 17:25:00 +0200 Subject: [PATCH 26/27] delete unnecessary code from search --- .../Search/DataTypes/InfoResult.cs | 44 +------------------ .../Search/DataTypes/SearchInformation.cs | 34 -------------- src/NRedisStack/Search/Document.cs | 16 ------- .../Search/{FT.CREATE => }/FTCreateParams.cs | 0 src/NRedisStack/Search/FieldName.cs | 11 ----- src/NRedisStack/Search/Group.cs | 8 ---- src/NRedisStack/Search/Query.cs | 13 ++---- src/NRedisStack/Search/Reducer.cs | 44 ++----------------- src/NRedisStack/Search/SearchResult.cs | 17 ------- 9 files changed, 8 insertions(+), 179 deletions(-) delete mode 100644 src/NRedisStack/Search/DataTypes/SearchInformation.cs rename src/NRedisStack/Search/{FT.CREATE => }/FTCreateParams.cs (100%) diff --git a/src/NRedisStack/Search/DataTypes/InfoResult.cs b/src/NRedisStack/Search/DataTypes/InfoResult.cs index 298288fb..81a8350d 100644 --- a/src/NRedisStack/Search/DataTypes/InfoResult.cs +++ b/src/NRedisStack/Search/DataTypes/InfoResult.cs @@ -9,10 +9,8 @@ public class InfoResult public string IndexName => GetString("index_name"); public Dictionary IndexOption => GetRedisResultDictionary("index_options"); - // public Dictionary IndexDefinition => GetRedisResultsDictionary("index_definition"); // TODO: fix this - // public Dictionary Attributes => GetRedisResultsDictionary("attributes"); // TODO: check if this is correct - public Dictionary[] Attributes => GetRedisResultDictionaryArray("attributes"); // TODO: check if this is correct + public Dictionary[] Attributes => GetRedisResultDictionaryArray("attributes"); public long NumDocs => GetLong("num_docs"); @@ -122,26 +120,6 @@ private Dictionary GetRedisResultDictionary(string key) } } - // TODO: check if this is needed: - // private Dictionary GetRedisResultsDictionary(string key) - // { - // if (_all.TryGetValue(key, out var value)) - // { - // var result = new Dictionary(); - - // foreach (RedisResult[] fv in (RedisResult[])value) - // { - // result.Add((string)fv[0], fv); - // } - - // return result; - // } - // else - // { - // return default; - // } - // } - private Dictionary[] GetRedisResultDictionaryArray(string key) { if (_all.TryGetValue(key, out var value)) @@ -166,25 +144,5 @@ private Dictionary[] GetRedisResultDictionaryArray(string k return default; } } - // private Dictionary[] GetRedisResultsDictionaryTry(string key) - // { - // if (_all.TryGetValue(key, out var value)) - // { - // var result = new List>(); - - // int i = 0; - // foreach (RedisResult[] fv in (RedisResult[])value) - // { - // var res = GetRedisResultDictionary((string)fv[i++]); - // result.Add(res); - // } - - // return result.ToArray(); - // } - // else - // { - // return default; - // } - // } } } \ No newline at end of file diff --git a/src/NRedisStack/Search/DataTypes/SearchInformation.cs b/src/NRedisStack/Search/DataTypes/SearchInformation.cs deleted file mode 100644 index 26c6cb63..00000000 --- a/src/NRedisStack/Search/DataTypes/SearchInformation.cs +++ /dev/null @@ -1,34 +0,0 @@ -// namespace NRedisStack.Search.DataTypes -// { -// /// -// /// This class represents the response for SEARCH.INFO command. -// /// This object has Read-only properties and cannot be generated outside a SEARCH.INFO response. -// /// -// public class SearchInformation -// { -// // TODO: work on it with someone from Search team -// // public string IndexName { get; private set; } -// // public string[] IndexOptions { get; private set; } -// // public long IndexDefinition { get; private set; } -// // public long UnmergedNodes { get; private set; } -// // public double MergedWeight { get; private set; } -// // public double UnmergedWeight { get; private set; } - -// // public long TotalCompressions { get; private set; } - - -// // internal SearchInformation(long compression, long capacity, long mergedNodes, -// // long unmergedNodes, double mergedWeight, -// // double unmergedWeight, long totalCompressions) - -// // { -// // Compression = compression; -// // Capacity = capacity; -// // MergedNodes = mergedNodes; -// // UnmergedNodes = unmergedNodes; -// // MergedWeight = mergedWeight; -// // UnmergedWeight = unmergedWeight; -// // TotalCompressions = totalCompressions; -// // } -// } -// } \ No newline at end of file diff --git a/src/NRedisStack/Search/Document.cs b/src/NRedisStack/Search/Document.cs index 472b6c00..a118adbf 100644 --- a/src/NRedisStack/Search/Document.cs +++ b/src/NRedisStack/Search/Document.cs @@ -63,22 +63,6 @@ public RedisValue this[string key] internal set { _properties[key] = value; } } - // TODO: check if this is needed: - //public bool HasProperty(string key) => _properties.ContainsKey(key); - - // internal static Document Parse(string docId, RedisResult result) - // { - // if (result == null || result.IsNull) return null; - // var arr = (RedisResult[])result; - // var doc = new Document(docId); - - // for(int i = 0; i < arr.Length; ) - // { - // doc[(string)arr[i++]] = (RedisValue)arr[i++]; - // } - // return doc; - // } - public Document Set(string field, RedisValue value) { this[field] = value; diff --git a/src/NRedisStack/Search/FT.CREATE/FTCreateParams.cs b/src/NRedisStack/Search/FTCreateParams.cs similarity index 100% rename from src/NRedisStack/Search/FT.CREATE/FTCreateParams.cs rename to src/NRedisStack/Search/FTCreateParams.cs diff --git a/src/NRedisStack/Search/FieldName.cs b/src/NRedisStack/Search/FieldName.cs index f107c784..2ce9f850 100644 --- a/src/NRedisStack/Search/FieldName.cs +++ b/src/NRedisStack/Search/FieldName.cs @@ -36,16 +36,5 @@ public FieldName As(string attribute) this.alias = attribute; return this; } - - // TODO: check if this is needed: - // public static FieldName[] Convert(params string[] names) - // { - // if (names == null) return null; - // FieldName[] fields = new FieldName[names.Length]; - // for (int i = 0; i < names.Length; i++) - // fields[i] = FieldName.Of(names[i]); - - // return fields; - // } } } \ No newline at end of file diff --git a/src/NRedisStack/Search/Group.cs b/src/NRedisStack/Search/Group.cs index 50d14fc6..57a894b3 100644 --- a/src/NRedisStack/Search/Group.cs +++ b/src/NRedisStack/Search/Group.cs @@ -43,13 +43,5 @@ internal void SerializeRedisArgs(List args) } _limit.SerializeRedisArgs(args); } - - // TODO: check if this is needed: - // public List getArgs() - // { - // List args = new List(); - // SerializeRedisArgs(args); - // return args; - // } } } \ No newline at end of file diff --git a/src/NRedisStack/Search/Query.cs b/src/NRedisStack/Search/Query.cs index 1a73232c..5ecdc504 100644 --- a/src/NRedisStack/Search/Query.cs +++ b/src/NRedisStack/Search/Query.cs @@ -262,7 +262,7 @@ internal void SerializeRedisArgs(List args) args.Add(SortBy); args.Add((SortAscending ? "ASC" : "DESC")); } - if (Payload != null) + if (Payload != null) { args.Add("PAYLOAD"); args.Add(Payload); @@ -343,25 +343,20 @@ internal void SerializeRedisArgs(List args) } } - // TODO: why duplicate if? - // if (_keys?.Length > 0) - // { - // args.Add("INKEYS"); - // args.Add(_keys.Length); - // args.AddRange(_keys); - // } if (_returnFields?.Length > 0) { args.Add("RETURN"); args.Add(_returnFields.Length); args.AddRange(_returnFields); } + else if (_returnFieldsNames?.Length > 0) { args.Add("RETURN"); int returnCountIndex = args.Count; int returnCount = 0; - foreach (FieldName fn in _returnFieldsNames) { + foreach (FieldName fn in _returnFieldsNames) + { returnCount += fn.AddCommandArguments(args); } diff --git a/src/NRedisStack/Search/Reducer.cs b/src/NRedisStack/Search/Reducer.cs index f9cb7b8c..0a870024 100644 --- a/src/NRedisStack/Search/Reducer.cs +++ b/src/NRedisStack/Search/Reducer.cs @@ -1,6 +1,4 @@ -using System.Collections.Generic; - -namespace NRedisStack.Search.Aggregation +namespace NRedisStack.Search.Aggregation { public abstract class Reducer { @@ -29,40 +27,13 @@ protected virtual void AddOwnArgs(List args) if (_field != null) args.Add(_field); } - /** - * @return The name of the reducer - */ - // public abstract string getName(); - - // public string getAlias() - // { - // return Alias; - // } - - // public Reducer setAlias(string alias) - // { - // this.Alias = alias; - // return this; - // } - - // public final Reducer as(string alias) { - // return setAlias(alias); - // } - public Reducer As(string alias) { Alias = alias; return this; } - // TODO: check if this is needed: - // public Reducer SetAliasAsField() - // { - // if (string.IsNullOrEmpty(_field)) throw new InvalidOperationException("Cannot set to field name since no field exists"); - // return As(_field); - // } - - internal void SerializeRedisArgs(List args) + internal void SerializeRedisArgs(List args) { int count = GetOwnArgsCount(); args.Add(count); @@ -72,14 +43,5 @@ internal void SerializeRedisArgs(List args) if (count != (after - before)) throw new InvalidOperationException($"Reducer '{ToString()}' incorrectly reported the arg-count as {count}, but added {after - before}"); } - - // TODO: check if this is needed: - // public List GetArgs() - // { - // List args = new List(); - // SerializeRedisArgs(args); - // return args; - // } -} - + } } \ No newline at end of file diff --git a/src/NRedisStack/Search/SearchResult.cs b/src/NRedisStack/Search/SearchResult.cs index 15b20a96..4f1476d3 100644 --- a/src/NRedisStack/Search/SearchResult.cs +++ b/src/NRedisStack/Search/SearchResult.cs @@ -78,22 +78,5 @@ internal SearchResult(RedisResult[] resp, bool hasContent, bool hasScores, bool docs.Add(Document.Load(id, score, payload, fields, scoreExplained)); } } - - // TODO: Check if this is needed: - // static IEnumerable FlatRedisResultArray(RedisResult[] collection) - // { - // foreach (var o in collection) - // { - // if (o.Type == ResultType.MultiBulk) - // { - // foreach (string t in FlatRedisResultArray((RedisResult[])o)) - // yield return t; - // } - // else - // { - // yield return o.ToString(); - // } - // } - // } } } \ No newline at end of file From 9766f27924fe2c33bf4b9d71a97b2d2d52a922d9 Mon Sep 17 00:00:00 2001 From: Shachar Pashchur Date: Wed, 11 Jan 2023 17:27:43 +0200 Subject: [PATCH 27/27] delete unnecessary code from TimeSeries --- .../TimeSeries/Extensions/BucketTimestampsExtensions.cs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/NRedisStack/TimeSeries/Extensions/BucketTimestampsExtensions.cs b/src/NRedisStack/TimeSeries/Extensions/BucketTimestampsExtensions.cs index bdca2a5a..b102e53d 100644 --- a/src/NRedisStack/TimeSeries/Extensions/BucketTimestampsExtensions.cs +++ b/src/NRedisStack/TimeSeries/Extensions/BucketTimestampsExtensions.cs @@ -12,14 +12,5 @@ internal static class TsBucketTimestampsExtensions TsBucketTimestamps.high => "+", _ => throw new ArgumentOutOfRangeException(nameof(bt), "Invalid TsBucketTimestamps type"), }; - - // TODO: check if this is needed: - // public static TsBucketTimestamps Asbt(string bt) => bt switch - // { - // "-" => TsBucketTimestamps.low, - // "~" => TsBucketTimestamps.mid, - // "+" => TsBucketTimestamps.high, - // _ => throw new ArgumentOutOfRangeException(nameof(bt), $"Invalid TsBucketTimestamps type '{bt}'"), - // }; } } \ No newline at end of file