diff --git a/src/Infrastructure/BotSharp.Abstraction/VectorStorage/Models/VectorFilter.cs b/src/Infrastructure/BotSharp.Abstraction/VectorStorage/Models/VectorFilter.cs index 88a1aca4..43ce6e04 100644 --- a/src/Infrastructure/BotSharp.Abstraction/VectorStorage/Models/VectorFilter.cs +++ b/src/Infrastructure/BotSharp.Abstraction/VectorStorage/Models/VectorFilter.cs @@ -9,11 +9,20 @@ public class VectorFilter : StringIdPagination /// Filter group: each item contains a logical operator and a list of key-value pairs /// [JsonPropertyName("filter_groups")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public IEnumerable? FilterGroups { get; set; } + /// + /// Order by a specific field + /// + [JsonPropertyName("order_by")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public VectorSort? OrderBy { get; set; } + /// /// Included payload fields /// [JsonPropertyName("fields")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public IEnumerable? Fields { get; set; } } \ No newline at end of file diff --git a/src/Infrastructure/BotSharp.Abstraction/VectorStorage/Models/VectorSort.cs b/src/Infrastructure/BotSharp.Abstraction/VectorStorage/Models/VectorSort.cs new file mode 100644 index 00000000..469018b0 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/VectorStorage/Models/VectorSort.cs @@ -0,0 +1,10 @@ +namespace BotSharp.Abstraction.VectorStorage.Models; + +public class VectorSort +{ + [JsonPropertyName("field")] + public string? Field { get; set; } + + [JsonPropertyName("order")] + public string? Order { get; set; } = "desc"; +} diff --git a/src/Plugins/BotSharp.Plugin.Qdrant/QdrantDb.cs b/src/Plugins/BotSharp.Plugin.Qdrant/QdrantDb.cs index f5465c32..9841ddab 100644 --- a/src/Plugins/BotSharp.Plugin.Qdrant/QdrantDb.cs +++ b/src/Plugins/BotSharp.Plugin.Qdrant/QdrantDb.cs @@ -144,6 +144,7 @@ public class QdrantDb : IVectorDb Filter? queryFilter = BuildQueryFilter(filter.FilterGroups); WithPayloadSelector? payloadSelector = BuildPayloadSelector(filter.Fields); + OrderBy? orderBy = BuildOrderBy(filter.OrderBy); var client = GetClient(); var tasks = new List(); @@ -154,6 +155,7 @@ public class QdrantDb : IVectorDb limit: (uint)filter.Size, offset: !string.IsNullOrWhiteSpace(filter.StartId) ? new PointId { Uuid = filter.StartId } : null, filter: queryFilter, + orderBy: orderBy, payloadSelector: payloadSelector, vectorsSelector: filter.WithVector); @@ -371,7 +373,13 @@ public class QdrantDb : IVectorDb var client = GetClient(); var schemaType = ConvertPayloadSchemaType(options.FieldSchemaType); - var result = await client.CreatePayloadIndexAsync(collectionName, options.FieldName, schemaType); + var result = await client.CreatePayloadIndexAsync(collectionName, options.FieldName, schemaType, indexParams: new() + { + IntegerIndexParams = new() + { + Range = true + } + }); return result.Status == UpdateStatus.Completed; } @@ -618,6 +626,20 @@ public class QdrantDb : IVectorDb return payloadSelector; } + private OrderBy? BuildOrderBy(VectorSort? sort) + { + if (string.IsNullOrWhiteSpace(sort?.Field)) + { + return null; + } + + return new OrderBy + { + Key = sort.Field, + Direction = sort.Order == "asc" ? Direction.Asc : Direction.Desc + }; + } + private PayloadSchemaType ConvertPayloadSchemaType(string schemaType) { PayloadSchemaType res;