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 58a5391e..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,23 +58,6 @@ public override int GetHashCode()
}
}
- ///
- /// 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 74db8abe..b6e16d92 100644
--- a/src/NRedisStack/Graph/GraphCacheList.cs
+++ b/src/NRedisStack/Graph/GraphCacheList.cs
@@ -52,15 +52,4 @@ private void GetProcedureInfo()
protected virtual ResultSet CallProcedure() =>
graph.CallProcedure(GraphName, Procedure);
}
-
- 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/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/src/NRedisStack/Graph/GraphCommands.cs b/src/NRedisStack/Graph/GraphCommands.cs
index 3779b961..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 cf374eb8..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
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 5f10cd74..a13f1049 100644
--- a/src/NRedisStack/Graph/RedisGraphUtilities.cs
+++ b/src/NRedisStack/Graph/RedisGraphUtilities.cs
@@ -22,21 +22,6 @@ 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();
- }
-
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/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/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/DataTypes/InfoResult.cs b/src/NRedisStack/Search/DataTypes/InfoResult.cs
index 1040f440..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");
- // 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,25 +120,6 @@ private Dictionary GetRedisResultDictionary(string key)
}
}
- 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))
@@ -165,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 96880700..a118adbf 100644
--- a/src/NRedisStack/Search/Document.cs
+++ b/src/NRedisStack/Search/Document.cs
@@ -63,21 +63,6 @@ public RedisValue this[string key]
internal set { _properties[key] = value; }
}
- 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/Extensions/IndexDataTypeExtensions.cs b/src/NRedisStack/Search/Extensions/IndexDataTypeExtensions.cs
deleted file mode 100644
index 13d59c3c..00000000
--- a/src/NRedisStack/Search/Extensions/IndexDataTypeExtensions.cs
+++ /dev/null
@@ -1,22 +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"),
- };
-
- 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/FTCreateParams.cs
similarity index 99%
rename from src/NRedisStack/Search/FT.CREATE/FTCreateParams.cs
rename to src/NRedisStack/Search/FTCreateParams.cs
index 755a86f1..96c56236 100644
--- a/src/NRedisStack/Search/FT.CREATE/FTCreateParams.cs
+++ b/src/NRedisStack/Search/FTCreateParams.cs
@@ -225,7 +225,7 @@ public void AddParams(List
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;
@@ -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)
@@ -265,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);
@@ -346,24 +343,20 @@ internal void SerializeRedisArgs(List args)
}
}
- 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);
}
@@ -440,7 +433,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 +484,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 +511,20 @@ public Query SetScorer(string scorer)
Scorer = scorer;
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
///
@@ -678,4 +685,4 @@ public Query SetExpander(String field)
return this;
}
}
-}
+}
\ No newline at end of file
diff --git a/src/NRedisStack/Search/Reducer.cs b/src/NRedisStack/Search/Reducer.cs
index 212de35c..0a870024 100644
--- a/src/NRedisStack/Search/Reducer.cs
+++ b/src/NRedisStack/Search/Reducer.cs
@@ -1,12 +1,7 @@
-using System.Collections.Generic;
-
-namespace NRedisStack.Search.Aggregation
+namespace NRedisStack.Search.Aggregation
{
public abstract class Reducer
{
-
- public override string ToString() => Name;
-
// internal Reducer(string field) => _field = field;
///
@@ -32,38 +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;
}
- 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);
@@ -73,13 +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}");
}
-
- public List GetArgs()
- {
- List args = new List();
- SerializeRedisArgs(args);
- return args;
}
-}
-
}
\ No newline at end of file
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/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..4f1476d3 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)
{
@@ -78,21 +78,5 @@ internal SearchResult(RedisResult[] resp, bool hasContent, bool hasScores, bool
docs.Add(Document.Load(id, score, payload, fields, scoreExplained));
}
}
-
- 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/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/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..b102e53d 100644
--- a/src/NRedisStack/TimeSeries/Extensions/BucketTimestampsExtensions.cs
+++ b/src/NRedisStack/TimeSeries/Extensions/BucketTimestampsExtensions.cs
@@ -12,13 +12,5 @@ internal static class TsBucketTimestampsExtensions
TsBucketTimestamps.high => "+",
_ => 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}'"),
- };
}
}
\ No newline at end of file
diff --git a/src/NRedisStack/TimeSeries/Extensions/ReduceExtensions.cs b/src/NRedisStack/TimeSeries/Extensions/ReduceExtensions.cs
index 005920c0..2485e2a6 100644
--- a/src/NRedisStack/TimeSeries/Extensions/ReduceExtensions.cs
+++ b/src/NRedisStack/TimeSeries/Extensions/ReduceExtensions.cs
@@ -12,13 +12,5 @@ internal static class ReduceExtensions
TsReduce.Max => "MAX",
_ => 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}'"),
- };
}
}
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/Bloom/BloomTests.cs b/tests/NRedisStack.Tests/Bloom/BloomTests.cs
index eb878e1b..a57a5314 100644
--- a/tests/NRedisStack.Tests/Bloom/BloomTests.cs
+++ b/tests/NRedisStack.Tests/Bloom/BloomTests.cs
@@ -385,10 +385,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
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]
diff --git a/tests/NRedisStack.Tests/Graph/GraphTests.cs b/tests/NRedisStack.Tests/Graph/GraphTests.cs
index 211d6702..b1ff64c1 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,26 +1947,56 @@ 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));
+ 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));
+ Assert.False(node1.Equals(null));
+ Assert.False(edge1.Equals(null));
+
+
var path = new NRedisStack.Graph.DataTypes.Path(new List() { node1, node2 },
new List() { edge1, edge2 });
@@ -1962,7 +2005,33 @@ 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));
+
+ Assert.True(record1.ToString() == "Record{values=Infinity}" || record1.ToString() == "Record{values=∞}");
+ Assert.NotEqual(record2.GetHashCode(), record1.GetHashCode());
+
+ 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);
+ }
+
+ [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
diff --git a/tests/NRedisStack.Tests/Search/SearchTests.cs b/tests/NRedisStack.Tests/Search/SearchTests.cs
index 5be01a74..fcdf95f8 100644
--- a/tests/NRedisStack.Tests/Search/SearchTests.cs
+++ b/tests/NRedisStack.Tests/Search/SearchTests.cs
@@ -24,23 +24,22 @@ 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)
- {
- nameValue.Add(item.Key);
- nameValue.Add(item.Value);
- }
- db.Execute("HSET", nameValue);
-
+ 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);
}
private void AddDocument(IDatabase db, string key, Dictionary objDictionary)
@@ -118,7 +117,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 +139,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));
@@ -666,6 +665,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());
@@ -965,6 +966,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()
{
@@ -1346,7 +1455,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")
@@ -1357,14 +1466,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 +1541,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 +1558,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 +1591,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 +1608,156 @@ 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]
+ public void TestQueryCommandBuilder()
+ {
+ var testQuery = new Query("foo").HighlightFields(new Query.HighlightTags("", ""), "txt")
+ .SetVerbatim()
+ .SetNoStopwords()
+ .SetWithScores()
+ .SetPayload("txt")
+ .SetLanguage("English")
+ .SetScorer("TFIDF")
+ //.SetExplainScore()
+ .SetWithPayloads()
+ .SetSortBy("txt", true)
+ .Limit(0, 11)
+ .SummarizeFields(20, 3, ";", "txt")
+ .LimitKeys("key1", "key2")
+ .LimitFields("txt")
+ .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",
+ "WITHPAYLOADS",
+ "LANGUAGE",
+ "English",
+ "SCORER",
+ "TFIDF",
+ "INFIELDS",
+ "1",
+ "txt",
+ "SORTBY",
+ "txt",
+ "ASC",
+ "PAYLOAD",
+ "txt",
+ "LIMIT",
+ "0",
+ "11",
+ "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 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()
+ {
+ // 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]
@@ -1512,11 +1768,11 @@ 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)
- .AddVectorField("vec", VectorField.VectorAlgo.FLAT, null);
+ .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, new Dictionary { { "dim", 10 } });
var buildCommand = SearchCommandBuilder.Create("idx", new FTCreateParams(), sc);
var expectedArgs = new List {
"idx",
@@ -1549,35 +1805,96 @@ public void TestFieldsCommandBuilder()
"CASESENSITIVE",
"vec",
"VECTOR",
- "FLAT"
+ "FLAT",
+ "1",
+ "dim",
+ "10"
};
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]);
+ Assert.Equal(expectedArgs[i], buildCommand.Args[i].ToString());
}
}
- [Fact]
- public void TestModulePrefixs1()
+ [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 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()
+ {
{
- {
- var conn = ConnectionMultiplexer.Connect("localhost");
- IDatabase db = conn.GetDatabase();
+ var conn = ConnectionMultiplexer.Connect("localhost");
+ IDatabase db = conn.GetDatabase();
- var ft = db.FT();
- // ...
- conn.Dispose();
- }
+ var ft = db.FT();
+ // ...
+ conn.Dispose();
+ }
- {
- var conn = ConnectionMultiplexer.Connect("localhost");
- IDatabase db = conn.GetDatabase();
+ {
+ var conn = ConnectionMultiplexer.Connect("localhost");
+ IDatabase db = conn.GetDatabase();
- var ft = db.FT();
- // ...
- conn.Dispose();
- }
+ var ft = db.FT();
+ // ...
+ conn.Dispose();
}
- }
\ No newline at end of file
+ }
+}
\ No newline at end of file
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]
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 });