Skip to content

Commit 7a35e47

Browse files
authored
Allowing SearchableAttribute to apply multiple times on one field (#473)
1 parent 893834a commit 7a35e47

File tree

5 files changed

+66
-1
lines changed

5 files changed

+66
-1
lines changed

src/Redis.OM/Modeling/SearchableAttribute.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace Redis.OM.Modeling
66
/// <summary>
77
/// Marks a field as searchable within a Redis Document.
88
/// </summary>
9-
[AttributeUsage(AttributeTargets.Property)]
9+
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
1010
public sealed class SearchableAttribute : SearchFieldAttribute
1111
{
1212
/// <summary>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using Redis.OM.Modeling;
2+
3+
namespace Redis.OM.Unit.Tests.RediSearchTests;
4+
5+
[Document(StorageType = StorageType.Json)]
6+
public class ObjectWithMultipleSearchableAttributes
7+
{
8+
[RedisIdField] public string Id { get; set; }
9+
10+
[Searchable(JsonPath = "$.City")]
11+
[Searchable(JsonPath = "$.State")]
12+
public Address Address { get; set; }
13+
}

test/Redis.OM.Unit.Tests/RediSearchTests/SearchFunctionalTests.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,5 +1227,23 @@ public void SaveDateTimeOffset()
12271227
Assert.Equal(intermediate.Offset,final.Offset);
12281228
Assert.Equal(intermediate.DateTime,final.DateTime);
12291229
}
1230+
1231+
[Fact]
1232+
public void TestMultipleSearchAttributesOnEmbeddedDoc()
1233+
{
1234+
var obj = new ObjectWithMultipleSearchableAttributes()
1235+
{
1236+
Address = new Address
1237+
{
1238+
City = "Long Beach Island",
1239+
State = "New Jersey"
1240+
}
1241+
};
1242+
1243+
var collection = new RedisCollection<ObjectWithMultipleSearchableAttributes>(_connection);
1244+
collection.Insert(obj);
1245+
var res = collection.First(x => x.Address.City == "Long" && x.Address.State == "New");
1246+
Assert.Equal(obj.Id, res.Id);
1247+
}
12301248
}
12311249
}

test/Redis.OM.Unit.Tests/RediSearchTests/SearchTests.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3839,5 +3839,37 @@ public void TestBasicQueryCastToIQueryable()
38393839
"0",
38403840
"1234");
38413841
}
3842+
3843+
[Fact]
3844+
public async Task TestIndexCreationWIthMultipleSearchFieldsForEmbeddedDoc()
3845+
{
3846+
_substitute.ExecuteAsync("FT.CREATE", Arg.Any<object[]>()).Returns("OK");
3847+
await _substitute.CreateIndexAsync(typeof(ObjectWithMultipleSearchableAttributes));
3848+
await _substitute.Received().ExecuteAsync("FT.CREATE",
3849+
"objectwithmultiplesearchableattributes-idx",
3850+
"ON",
3851+
"Json",
3852+
"PREFIX",
3853+
"1",
3854+
"Redis.OM.Unit.Tests.RediSearchTests.ObjectWithMultipleSearchableAttributes:",
3855+
"SCHEMA",
3856+
"$.Address.City", "AS", "Address_City", "TEXT",
3857+
"$.Address.State", "AS", "Address_State", "TEXT");
3858+
}
3859+
3860+
[Fact]
3861+
public async Task TestMultipleTextSearchOnEmbeddedDoc()
3862+
{
3863+
_substitute.ClearSubstitute();
3864+
_substitute.ExecuteAsync(Arg.Any<string>(), Arg.Any<object[]>()).Returns(_mockReply);
3865+
var collection = new RedisCollection<ObjectWithMultipleSearchableAttributes>(_substitute);
3866+
await collection.Where(x => x.Address.City == "Long" && x.Address.State == "New").ToListAsync();
3867+
await _substitute.Received().ExecuteAsync("FT.SEARCH",
3868+
"objectwithmultiplesearchableattributes-idx",
3869+
"((@Address_City:\"Long\") (@Address_State:\"New\"))",
3870+
"LIMIT",
3871+
"0",
3872+
"100");
3873+
}
38423874
}
38433875
}

test/Redis.OM.Unit.Tests/RedisSetupCollection.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public RedisSetup()
3030
Connection.CreateIndex(typeof(BasicJsonObjectTestSave));
3131
Connection.CreateIndex(typeof(SelectTestObject));
3232
Connection.CreateIndex(typeof(ObjectWithDateTimeOffsetJson));
33+
Connection.CreateIndex(typeof(ObjectWithMultipleSearchableAttributes));
3334
}
3435

3536
private IRedisConnectionProvider _provider;
@@ -62,6 +63,7 @@ public void Dispose()
6263
Connection.DropIndexAndAssociatedRecords(typeof(BasicJsonObjectTestSave));
6364
Connection.DropIndexAndAssociatedRecords(typeof(SelectTestObject));
6465
Connection.DropIndexAndAssociatedRecords(typeof(ObjectWithDateTimeOffsetJson));
66+
Connection.DropIndexAndAssociatedRecords(typeof(ObjectWithMultipleSearchableAttributes));
6567
}
6668
}
6769
}

0 commit comments

Comments
 (0)