diff --git a/src/NRedisStack/Search/DataTypes/InfoResult.cs b/src/NRedisStack/Search/DataTypes/InfoResult.cs index b676ca24..f931df92 100644 --- a/src/NRedisStack/Search/DataTypes/InfoResult.cs +++ b/src/NRedisStack/Search/DataTypes/InfoResult.cs @@ -1,14 +1,20 @@ -using StackExchange.Redis; +using System.Reflection.Emit; +using StackExchange.Redis; namespace NRedisStack.Search.DataTypes; public class InfoResult { private readonly Dictionary _all = new(); - private static readonly string[] booleanAttributes = { "SORTABLE", "UNF", "NOSTEM", "NOINDEX", "CASESENSITIVE", "WITHSUFFIXTRIE" }; + private Dictionary[] _attributes; + private Dictionary _indexOption; + private Dictionary _gcStats; + private Dictionary _cursorStats; + + private static readonly string[] booleanAttributes = { "SORTABLE", "UNF", "NOSTEM", "NOINDEX", "CASESENSITIVE", "WITHSUFFIXTRIE", "INDEXEMPTY", "INDEXMISSING" }; public string IndexName => GetString("index_name")!; - public Dictionary IndexOption => GetRedisResultDictionary("index_options")!; - public Dictionary[] Attributes => GetRedisResultDictionaryArray("attributes")!; + public Dictionary IndexOption => _indexOption = _indexOption ?? GetRedisResultDictionary("index_options")!; + public Dictionary[] Attributes => _attributes = _attributes ?? GetAttributesAsDictionaryArray()!; public long NumDocs => GetLong("num_docs"); public string MaxDocId => GetString("max_doc_id")!; public long NumTerms => GetLong("num_terms"); @@ -48,9 +54,9 @@ public class InfoResult public long NumberOfUses => GetLong("number_of_uses"); - public Dictionary GcStats => GetRedisResultDictionary("gc_stats")!; + public Dictionary GcStats => _gcStats = _gcStats ?? GetRedisResultDictionary("gc_stats")!; - public Dictionary CursorStats => GetRedisResultDictionary("cursor_stats")!; + public Dictionary CursorStats => _cursorStats = _cursorStats ?? GetRedisResultDictionary("cursor_stats")!; public InfoResult(RedisResult result) { @@ -94,24 +100,29 @@ private double GetDouble(string key) return result; } - private Dictionary[]? GetRedisResultDictionaryArray(string key) + private Dictionary[]? GetAttributesAsDictionaryArray() { - if (!_all.TryGetValue(key, out var value)) return default; + if (!_all.TryGetValue("attributes", out var value)) return default; var values = (RedisResult[])value!; var result = new Dictionary[values.Length]; for (int i = 0; i < values.Length; i++) { - var fv = (RedisResult[])values[i]!; var dict = new Dictionary(); - for (int j = 0; j < fv.Length; j += 2) + + IEnumerable enumerable = (RedisResult[])values[i]!; + IEnumerator results = enumerable.GetEnumerator(); + while (results.MoveNext()) { - if (booleanAttributes.Contains((string)fv[j]!)) + string attribute = (string)results.Current; + // if its boolean attributes add itself to the dictionary and continue + if (booleanAttributes.Contains(attribute)) { - dict.Add((string)fv[j]!, fv[j--]); + dict.Add(attribute, results.Current); } else - { - dict.Add((string)fv[j]!, fv[j + 1]); + {//if its not a boolean attribute, add the next item as value to the dictionary + results.MoveNext(); ; + dict.Add(attribute, results.Current); } } result[i] = dict; diff --git a/tests/NRedisStack.Tests/Search/SearchTests.cs b/tests/NRedisStack.Tests/Search/SearchTests.cs index 2ed10466..a5acfb68 100644 --- a/tests/NRedisStack.Tests/Search/SearchTests.cs +++ b/tests/NRedisStack.Tests/Search/SearchTests.cs @@ -887,6 +887,40 @@ public void AlterAddSortable() Assert.Equal(4, info.CursorStats.Count); } + [SkipIfRedis(Comparison.LessThan, "7.3.0")] + public void InfoWithIndexEmptyAndIndexMissing() + { + IDatabase db = redisFixture.Redis.GetDatabase(); + db.Execute("FLUSHALL"); + var ft = db.FT(2); + var vectorAttrs = new Dictionary() + { + ["TYPE"] = "FLOAT32", + ["DIM"] = "2", + ["DISTANCE_METRIC"] = "L2", + }; + + Schema sc = new Schema() + .AddTextField("text1", 1.0, emptyIndex: true, missingIndex: true) + .AddTagField("tag1", emptyIndex: true, missingIndex: true) + .AddNumericField("numeric1", missingIndex: true) + .AddGeoField("geo1", missingIndex: true) + .AddGeoShapeField("geoshape1", Schema.GeoShapeField.CoordinateSystem.FLAT, missingIndex: true) + .AddVectorField("vector1", Schema.VectorField.VectorAlgo.FLAT, vectorAttrs, missingIndex: true); + Assert.True(ft.Create(index, FTCreateParams.CreateParams(), sc)); + + var info = ft.Info(index); + var attributes = info.Attributes; + foreach (var attribute in attributes) + { + Assert.True(attribute.ContainsKey("INDEXMISSING")); + if (attribute["attribute"].ToString() == "text1" || attribute["attribute"].ToString() == "tag1") + { + Assert.True(attribute.ContainsKey("INDEXEMPTY")); + } + } + } + [SkipIfRedis(Is.OSSCluster, Is.Enterprise)] public async Task AlterAddSortableAsync() {