diff --git a/src/FreeRedis.DistributedCache/FreeRedis.DistributedCache.csproj b/src/FreeRedis.DistributedCache/FreeRedis.DistributedCache.csproj index c298b77..c1542fb 100644 --- a/src/FreeRedis.DistributedCache/FreeRedis.DistributedCache.csproj +++ b/src/FreeRedis.DistributedCache/FreeRedis.DistributedCache.csproj @@ -4,7 +4,7 @@ FreeRedis.DistributedCache FreeRedis.DistributedCache FreeRedis.DistributedCache - 1.3.5 + 1.3.6 true https://github.com/2881099/FreeRedis 分布式缓存 FreeRedis 实现 Microsoft.Extensions.Caching diff --git a/src/FreeRedis.OpenTelemetry/FreeRedis.OpenTelemetry.csproj b/src/FreeRedis.OpenTelemetry/FreeRedis.OpenTelemetry.csproj index 309d4d3..7a76397 100644 --- a/src/FreeRedis.OpenTelemetry/FreeRedis.OpenTelemetry.csproj +++ b/src/FreeRedis.OpenTelemetry/FreeRedis.OpenTelemetry.csproj @@ -5,7 +5,7 @@ FreeRedis.OpenTelemetry FreeRedis.OpenTelemetry FreeRedis.OpenTelemetry - 1.3.5 + 1.3.6 true https://github.com/2881099/FreeRedis https://github.com/2881099/FreeRedis diff --git a/src/FreeRedis/FreeRedis.csproj b/src/FreeRedis/FreeRedis.csproj index c288bb2..435329c 100644 --- a/src/FreeRedis/FreeRedis.csproj +++ b/src/FreeRedis/FreeRedis.csproj @@ -5,7 +5,7 @@ FreeRedis FreeRedis FreeRedis - 1.3.5 + 1.3.6 true https://github.com/2881099/FreeRedis FreeRedis is .NET redis client, supports cluster, sentinel, master-slave, pipeline, transaction and connection pool. diff --git a/src/FreeRedis/RedisClient/Modules/RediSearchBuilder/FtDocumentRepository.cs b/src/FreeRedis/RedisClient/Modules/RediSearchBuilder/FtDocumentRepository.cs index b7df736..86a938b 100644 --- a/src/FreeRedis/RedisClient/Modules/RediSearchBuilder/FtDocumentRepository.cs +++ b/src/FreeRedis/RedisClient/Modules/RediSearchBuilder/FtDocumentRepository.cs @@ -18,8 +18,9 @@ internal protected class DocumentSchemaInfo public Type DocumentType { get; set; } public FtDocumentAttribute DocumentAttribute { get; set; } public PropertyInfo KeyProperty { get; set; } - public List Fields { get; set; } - public Dictionary FieldsMap { get; set; } + public List Fields { get; set; } = new List(); + public Dictionary FieldsMap { get; set; } = new Dictionary(); + public Dictionary FieldsMapRead { get; set; } = new Dictionary(); } internal protected class DocumentSchemaFieldInfo { @@ -41,23 +42,27 @@ public FtDocumentRepository(RedisClient client) { attribute = p.GetCustomAttributes(false).FirstOrDefault(a => a is FtFieldAttribute) as FtFieldAttribute, property = p - }).Where(a => a.attribute != null).ToList(); - if (fieldProprties.Any() == false) throw new Exception($"Not found: [FtFieldAttribute]"); + }).Where(a => a.attribute != null); var schema = new DocumentSchemaInfo { DocumentType = type, - DocumentAttribute = type.GetCustomAttributes(false).FirstOrDefault(a => a is FtDocumentAttribute) as FtDocumentAttribute, - KeyProperty = type.GetProperties().FirstOrDefault(p => p.GetCustomAttributes(false).FirstOrDefault(a => a is FtKeyAttribute) != null), }; - var fields = fieldProprties.Select(a => new DocumentSchemaFieldInfo + foreach (var fieldProperty in fieldProprties) { - DocumentSchema = schema, - Property = a.property, - FieldAttribute = a.attribute, - FieldType = GetMapFieldType(a.property, a.attribute) - }).ToList(); - schema.Fields = fields; - schema.FieldsMap = fields.ToDictionary(a => a.Property.Name, a => a); + var field = new DocumentSchemaFieldInfo + { + DocumentSchema = schema, + Property = fieldProperty.property, + FieldAttribute = fieldProperty.attribute, + FieldType = GetMapFieldType(fieldProperty.property, fieldProperty.attribute) + }; + schema.Fields.Add(field); + schema.FieldsMap[field.Property.Name] = field; + schema.FieldsMapRead[field.FieldAttribute.Name] = field; + } + if (schema.Fields.Any() == false) throw new Exception($"Not found: [FtFieldAttribute]"); + schema.DocumentAttribute = type.GetCustomAttributes(false).FirstOrDefault(a => a is FtDocumentAttribute) as FtDocumentAttribute; + schema.KeyProperty = type.GetProperties().FirstOrDefault(p => p.GetCustomAttributes(false).FirstOrDefault(a => a is FtKeyAttribute) != null); return schema; }); } @@ -250,28 +255,41 @@ internal protected List> ParseSelectorExpression(Ex { var fieldValues = new List>(); if (selector is LambdaExpression lambdaExp) selector = lambdaExp.Body; - - if (selector.NodeType == ExpressionType.New) + if (selector is UnaryExpression unaryExp) selector = unaryExp.Operand; + switch (selector.NodeType) { - var newExp = selector as NewExpression; - for (var a = 0; a < newExp?.Members?.Count; a++) - { - var left = newExp.Members[a].Name; - var right = ParseQueryExpression(newExp.Arguments[a], new ParseQueryExpressionOptions { IsQuoteFieldName = isQuoteFieldName }); - fieldValues.Add(new KeyValuePair(left, right)); - } - } - else if (selector.NodeType == ExpressionType.MemberInit) - { - var initExp = selector as MemberInitExpression; - for (var a = 0; a < initExp?.Bindings.Count; a++) - { - var initAssignExp = (initExp.Bindings[a] as MemberAssignment); - if (initAssignExp == null) continue; - var left = initAssignExp.Member.Name; - var right = ParseQueryExpression(initAssignExp.Expression, new ParseQueryExpressionOptions { IsQuoteFieldName = isQuoteFieldName }); - fieldValues.Add(new KeyValuePair(left, right)); - } + case ExpressionType.MemberAccess: + { + var memExp = selector as MemberExpression; + var left = memExp.Member.Name; + var right = ParseQueryExpression(memExp, new ParseQueryExpressionOptions { IsQuoteFieldName = isQuoteFieldName }); + fieldValues.Add(new KeyValuePair(left, right)); + } + break; + case ExpressionType.New: + { + var newExp = selector as NewExpression; + for (var a = 0; a < newExp?.Members?.Count; a++) + { + var left = newExp.Members[a].Name; + var right = ParseQueryExpression(newExp.Arguments[a], new ParseQueryExpressionOptions { IsQuoteFieldName = isQuoteFieldName }); + fieldValues.Add(new KeyValuePair(left, right)); + } + } + break; + case ExpressionType.MemberInit: + { + var initExp = selector as MemberInitExpression; + for (var a = 0; a < initExp?.Bindings.Count; a++) + { + var initAssignExp = (initExp.Bindings[a] as MemberAssignment); + if (initAssignExp == null) continue; + var left = initAssignExp.Member.Name; + var right = ParseQueryExpression(initAssignExp.Expression, new ParseQueryExpressionOptions { IsQuoteFieldName = isQuoteFieldName }); + fieldValues.Add(new KeyValuePair(left, right)); + } + } + break; } return fieldValues; } @@ -736,16 +754,21 @@ List FetchResult(SearchResult result) foreach (var kv in doc.Body) { var name = kv.Key.Replace("-", "_"); - var prop = ttype.GetPropertyOrFieldIgnoreCase(name); - if (prop == null) continue; + FtDocumentRepository.DocumentSchemaFieldInfo field = null; + if (_searchBuilder._return.Any()) //属性匹配 + { + var prop = ttype.GetPropertyOrFieldIgnoreCase(name); + if (prop == null || !_repository._schema.FieldsMap.TryGetValue(prop.Name, out field)) continue; + } + else if (!_repository._schema.FieldsMapRead.TryGetValue(name, out field)) continue; if (kv.Value == null) continue; - if (kv.Value is string valstr && _repository._schema.FieldsMap.TryGetValue(prop.Name, out var field) && field.FieldType == FieldType.Tag) - ttype.SetPropertyOrFieldValue(item, prop.Name, + if (kv.Value is string valstr && field.FieldType == FieldType.Tag) + ttype.SetPropertyOrFieldValue(item, field.Property.Name, field.Property.PropertyType.IsArrayOrList() ? field.Property.PropertyType.FromObject(valstr.Split(new[] { (field.FieldAttribute as FtTagFieldAttribute).Separator ?? "," }, StringSplitOptions.None)) : valstr ); else - ttype.SetPropertyOrFieldValue(item, prop.Name, prop.GetPropertyOrFieldType().FromObject(kv.Value)); + ttype.SetPropertyOrFieldValue(item, field.Property.Name, field.Property.PropertyType.FromObject(kv.Value)); } var itemId = doc.Id; if (!string.IsNullOrEmpty(prefix)) diff --git a/src/FreeRedis/RedisClient/Modules/RediSearchBuilder/SearchBuilder.cs b/src/FreeRedis/RedisClient/Modules/RediSearchBuilder/SearchBuilder.cs index cc3fc69..87ee52e 100644 --- a/src/FreeRedis/RedisClient/Modules/RediSearchBuilder/SearchBuilder.cs +++ b/src/FreeRedis/RedisClient/Modules/RediSearchBuilder/SearchBuilder.cs @@ -169,32 +169,32 @@ public Task ExecuteAsync() } #endif - private bool _noContent, _verbatim, _noStopwords, _withScores, _withPayloads, _withSortKeys; - private List _filters = new List(); - private List _geoFilter = new List(); - private List _inKeys = new List(); - private List _inFields = new List(); - private List _return = new List(); - private bool _sumarize; - private List _sumarizeFields = new List(); - private long _sumarizeFrags = -1; - private long _sumarizeLen = -1; - private string _sumarizeSeparator; - private bool _highLight; - private List _highLightFields = new List(); - private object[] _highLightTags; - private decimal _slop = -1; - private long _timeout = -1; - private bool _inOrder; - private string _language; - private string _expander, _scorer; - private bool _explainScore; - private string _payLoad; - private string _sortBy; - private bool _sortByDesc; - private long _limitOffset, _limitNum = 10; - private List _params = new List(); - private int _dialect; + internal bool _noContent, _verbatim, _noStopwords, _withScores, _withPayloads, _withSortKeys; + internal List _filters = new List(); + internal List _geoFilter = new List(); + internal List _inKeys = new List(); + internal List _inFields = new List(); + internal List _return = new List(); + internal bool _sumarize; + internal List _sumarizeFields = new List(); + internal long _sumarizeFrags = -1; + internal long _sumarizeLen = -1; + internal string _sumarizeSeparator; + internal bool _highLight; + internal List _highLightFields = new List(); + internal object[] _highLightTags; + internal decimal _slop = -1; + internal long _timeout = -1; + internal bool _inOrder; + internal string _language; + internal string _expander, _scorer; + internal bool _explainScore; + internal string _payLoad; + internal string _sortBy; + internal bool _sortByDesc; + internal long _limitOffset, _limitNum = 10; + internal List _params = new List(); + internal int _dialect; public SearchBuilder NoContent(bool value = true) { diff --git a/test/Unit/FreeRedis.Tests/RedisClientTests/ModulesTests/RediSearchTests.cs b/test/Unit/FreeRedis.Tests/RedisClientTests/ModulesTests/RediSearchTests.cs index bfa2d4c..aca4b33 100644 --- a/test/Unit/FreeRedis.Tests/RedisClientTests/ModulesTests/RediSearchTests.cs +++ b/test/Unit/FreeRedis.Tests/RedisClientTests/ModulesTests/RediSearchTests.cs @@ -13,7 +13,7 @@ public class RediSearchTests : TestBase protected static ConnectionStringBuilder Connection = new ConnectionStringBuilder() { - Host = "8.154.26.119", + Host = "8.154.26.119:63791", MaxPoolSize = 10, Protocol = RedisProtocol.RESP2, ClientName = "FreeRedis", @@ -36,16 +36,16 @@ class TestDoc [FtKey] public int Id { get; set; } - [FtTextField("title", Weight = 5.0)] + [FtTextField("title22", Weight = 5.0)] public string Title { get; set; } - [FtTextField("category")] + [FtTextField("category22")] public string Category { get; set; } - [FtTextField("content", Weight = 1.0, NoIndex = true)] + [FtTextField("content22", Weight = 1.0, NoIndex = true)] public string Content { get; set; } - [FtTagField("tags")] + [FtTagField("tags22")] public string Tags { get; set; } [FtNumericField("views")] @@ -111,16 +111,16 @@ class TagMapListIndex [FtKey] public int Id { get; set; } - [FtTextField("title", Weight = 5.0)] + [FtTextField("title1", Weight = 5.0)] public string Title { get; set; } - [FtTextField("category")] + [FtTextField("category1")] public string Category { get; set; } - [FtTextField("content", Weight = 1.0, NoIndex = true)] + [FtTextField("content2", Weight = 1.0, NoIndex = true)] public string Content { get; set; } - [FtTagField("tags")] + [FtTagField("tags11")] public List Tags { get; set; } [FtNumericField("views")]