diff --git a/src/DataStax.AstraDB.DataApi/Core/Query/FindEnumerator.cs b/src/DataStax.AstraDB.DataApi/Core/Query/FindEnumerator.cs index 2df97c2b..3507a876 100644 --- a/src/DataStax.AstraDB.DataApi/Core/Query/FindEnumerator.cs +++ b/src/DataStax.AstraDB.DataApi/Core/Query/FindEnumerator.cs @@ -124,6 +124,10 @@ public FindEnumerator Sort(TSort sortBuilder) /// var similarity = result.Similarity; /// /// + /// + /// When searching on Tables, the field in the row class should be given the + /// attribute instead. + /// public FindEnumerator IncludeSimilarity(bool includeSimilarity) { return UpdateOptions(options => options.IncludeSimilarity = includeSimilarity); diff --git a/src/DataStax.AstraDB.DataApi/SerDes/ColumnMappingAttribute.cs b/src/DataStax.AstraDB.DataApi/SerDes/ColumnMappingAttribute.cs new file mode 100644 index 00000000..9b686568 --- /dev/null +++ b/src/DataStax.AstraDB.DataApi/SerDes/ColumnMappingAttribute.cs @@ -0,0 +1,40 @@ +/* + * Copyright DataStax, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace DataStax.AstraDB.DataApi.SerDes; + +using System; + +/// +/// Marks a property on a table row as a special field for the database's use. +/// +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] +public class ColumnMappingAttribute : Attribute +{ + /// + /// The type of special field this property is mapped to + /// + public ColumnMappingField Field { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The type of special field this property is mapped to + public ColumnMappingAttribute(ColumnMappingField field) + { + Field = field; + } +} \ No newline at end of file diff --git a/src/DataStax.AstraDB.DataApi/SerDes/ColumnMappingField.cs b/src/DataStax.AstraDB.DataApi/SerDes/ColumnMappingField.cs new file mode 100644 index 00000000..ec66f982 --- /dev/null +++ b/src/DataStax.AstraDB.DataApi/SerDes/ColumnMappingField.cs @@ -0,0 +1,26 @@ +/* + * Copyright DataStax, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace DataStax.AstraDB.DataApi.SerDes; + +/// +/// Special field types for table rows. +/// +public enum ColumnMappingField +{ + /// On read operations only, deserializes the similarity result for vector comparisons + Similarity, +} diff --git a/src/DataStax.AstraDB.DataApi/SerDes/DocumentMappingAttribute.cs b/src/DataStax.AstraDB.DataApi/SerDes/DocumentMappingAttribute.cs index 314e4910..f64483ec 100644 --- a/src/DataStax.AstraDB.DataApi/SerDes/DocumentMappingAttribute.cs +++ b/src/DataStax.AstraDB.DataApi/SerDes/DocumentMappingAttribute.cs @@ -19,7 +19,7 @@ namespace DataStax.AstraDB.DataApi.SerDes; using System; /// -/// Marks a property on a document as a special field for the database's use. +/// Marks a property on a collection document as a special field for the database's use. /// [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] public class DocumentMappingAttribute : Attribute diff --git a/src/DataStax.AstraDB.DataApi/SerDes/DocumentMappingField.cs b/src/DataStax.AstraDB.DataApi/SerDes/DocumentMappingField.cs index 3bb47dcd..9575b025 100644 --- a/src/DataStax.AstraDB.DataApi/SerDes/DocumentMappingField.cs +++ b/src/DataStax.AstraDB.DataApi/SerDes/DocumentMappingField.cs @@ -17,7 +17,7 @@ namespace DataStax.AstraDB.DataApi.SerDes; /// -/// Special field types +/// Special field types for collection documents. /// public enum DocumentMappingField { diff --git a/src/DataStax.AstraDB.DataApi/SerDes/RowConverter.cs b/src/DataStax.AstraDB.DataApi/SerDes/RowConverter.cs index 7b81621f..dff5207a 100644 --- a/src/DataStax.AstraDB.DataApi/SerDes/RowConverter.cs +++ b/src/DataStax.AstraDB.DataApi/SerDes/RowConverter.cs @@ -40,7 +40,9 @@ public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerial T instance = Activator.CreateInstance(); var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance) - .Where(p => p.CanWrite && !p.GetCustomAttributes().Any()) + .Where(p => p.CanWrite && + (!p.GetCustomAttributes().Any() || + p.GetCustomAttribute()?.Field == ColumnMappingField.Similarity)) .ToDictionary(p => GetPropertyName(p, true), p => p); while (reader.Read()) @@ -228,10 +230,10 @@ public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions private static string GetPropertyName(PropertyInfo property, bool forDeserialization) { - var documentMappingAttribute = property.GetCustomAttribute(); - if (documentMappingAttribute != null && forDeserialization) + var columnMappingAttribute = property.GetCustomAttribute(); + if (columnMappingAttribute != null && forDeserialization) { - if (documentMappingAttribute.Field == DocumentMappingField.Similarity) + if (columnMappingAttribute.Field == ColumnMappingField.Similarity) { return "$similarity"; } diff --git a/test/DataStax.AstraDB.DataApi.IntegrationTests/TestObjects.cs b/test/DataStax.AstraDB.DataApi.IntegrationTests/TestObjects.cs index 7b4d6a26..809249de 100644 --- a/test/DataStax.AstraDB.DataApi.IntegrationTests/TestObjects.cs +++ b/test/DataStax.AstraDB.DataApi.IntegrationTests/TestObjects.cs @@ -19,7 +19,7 @@ public class SimpleObjectWithVector public class SimpleObjectWithVectorSearchResult : SimpleObjectWithVector { - [DocumentMapping(DocumentMappingField.Similarity)] + [ColumnMapping(ColumnMappingField.Similarity)] public double? Similarity { get; set; } } @@ -225,7 +225,7 @@ public class RowEventByDay public class RowBookWithSimilarity : RowBook { - [DocumentMapping(DocumentMappingField.Similarity)] + [ColumnMapping(ColumnMappingField.Similarity)] public double Similarity { get; set; } } diff --git a/test/DataStax.AstraDB.DataApi.IntegrationTests/Tests/AdditionalTableTests.cs b/test/DataStax.AstraDB.DataApi.IntegrationTests/Tests/AdditionalTableTests.cs index 09eb02d8..a9bd6784 100644 --- a/test/DataStax.AstraDB.DataApi.IntegrationTests/Tests/AdditionalTableTests.cs +++ b/test/DataStax.AstraDB.DataApi.IntegrationTests/Tests/AdditionalTableTests.cs @@ -553,7 +553,8 @@ public async Task FindOne_Vector() var result = await table.FindOneAsync(null, new TableFindOptions() { Sort = sort, IncludeSimilarity = true }); - Assert.NotEqual(0, result.Similarity); + Assert.NotNull(result.Similarity); + Assert.True(result.Similarity > 0); } finally {