Skip to content

Commit

Permalink
refactor: use mvi filter fields for get/delete items (#532)
Browse files Browse the repository at this point in the history
We are in the process of migrating MVI delete item batch, get item batch, and get item metadata batch to use a filter expression to select items to delete (get) as opposed to a list of id's. For convenience, we will still allow users to select items with a list of id's from the top level methods. This PR migrates the backend.

As part of the migration we are also moving away from the hit/miss pattern for get item batch and get item metadata batch response messages. While the hit/miss pattern made sense for when we only selected items by id, it no longer makes sense for when a user supplies a general filter expression. What's more, previously when we read the hit/miss responses, we built a dictionary containing only the hits, so the distinction wasn't as important.

In future PRs we will add overloads to also use a filter expression from delete and get item methods.
  • Loading branch information
malandis authored Feb 12, 2024
1 parent 7cbcf27 commit 038b00d
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 32 deletions.
54 changes: 23 additions & 31 deletions src/Momento.Sdk/Internal/VectorIndexDataClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,26 +83,14 @@ public async Task<GetItemBatchResponse> GetItemBatchAsync(string indexName, IEnu
var request = new _GetItemBatchRequest()
{
IndexName = indexName,
Ids = { ids },
Filter = idsToFilterExpression(ids),
MetadataFields = new _MetadataRequest { All = new _MetadataRequest.Types.All() }
};

var response =
await grpcManager.Client.GetItemBatchAsync(request, new CallOptions(deadline: CalculateDeadline()));
var items = new Dictionary<string, Item>();
foreach (var item in response.ItemResponse)
{
switch (item.ResponseCase)
{
case _ItemResponse.ResponseOneofCase.Hit:
items[item.Hit.Id] = new(item.Hit.Id, item.Hit.Vector.Elements.ToList(), Convert(item.Hit.Metadata));
break;
case _ItemResponse.ResponseOneofCase.Miss:
break;
default:
throw new UnknownException($"Unknown item response type {item.ResponseCase}");
}
}
var items = response.ItemResponse.ToDictionary(
item => item.Id, item => new Item(item.Id, item.Vector.Elements.ToList(), Convert(item.Metadata)));
return _logger.LogTraceVectorIndexRequestSuccess(REQUEST_GET_ITEM_BATCH, indexName,
new GetItemBatchResponse.Success(items));
}
Expand All @@ -123,27 +111,15 @@ public async Task<GetItemMetadataBatchResponse> GetItemMetadataBatchAsync(string
var request = new _GetItemMetadataBatchRequest()
{
IndexName = indexName,
Ids = { ids },
Filter = idsToFilterExpression(ids),
MetadataFields = new _MetadataRequest { All = new _MetadataRequest.Types.All() }
};

var response =
await grpcManager.Client.GetItemMetadataBatchAsync(request,
new CallOptions(deadline: CalculateDeadline()));
var items = new Dictionary<string, Dictionary<string, MetadataValue>>();
foreach (var item in response.ItemMetadataResponse)
{
switch (item.ResponseCase)
{
case _ItemMetadataResponse.ResponseOneofCase.Hit:
items[item.Hit.Id] = Convert(item.Hit.Metadata);
break;
case _ItemMetadataResponse.ResponseOneofCase.Miss:
break;
default:
throw new UnknownException($"Unknown item response type {item.ResponseCase}");
}
}
var items = response.ItemMetadataResponse.ToDictionary(
item => item.Id, item => Convert(item.Metadata));
return _logger.LogTraceVectorIndexRequestSuccess(REQUEST_GET_ITEM_METADATA_BATCH, indexName,
new GetItemMetadataBatchResponse.Success(items));
}
Expand All @@ -154,14 +130,30 @@ await grpcManager.Client.GetItemMetadataBatchAsync(request,
}
}

/// <summary>
/// Convert a list of ids to an id-in-set filter expression.
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
private static _FilterExpression idsToFilterExpression(IEnumerable<string> ids)
{
return new _FilterExpression
{
IdInSetExpression = new _IdInSetExpression()
{
Ids = { ids }
}
};
}

const string REQUEST_DELETE_ITEM_BATCH = "DELETE_ITEM_BATCH";
public async Task<DeleteItemBatchResponse> DeleteItemBatchAsync(string indexName, IEnumerable<string> ids)
{
try
{
_logger.LogTraceVectorIndexRequest(REQUEST_DELETE_ITEM_BATCH, indexName);
CheckValidIndexName(indexName);
var request = new _DeleteItemBatchRequest() { IndexName = indexName, Ids = { ids } };
var request = new _DeleteItemBatchRequest() { IndexName = indexName, Filter = idsToFilterExpression(ids) };

await grpcManager.Client.DeleteItemBatchAsync(request, new CallOptions(deadline: CalculateDeadline()));
return _logger.LogTraceVectorIndexRequestSuccess(REQUEST_DELETE_ITEM_BATCH, indexName,
Expand Down
2 changes: 1 addition & 1 deletion src/Momento.Sdk/Momento.Sdk.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
<ItemGroup>
<PackageReference Include="Grpc.Net.Client" Version="2.49.0" />
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="7.0.0" />
<PackageReference Include="Momento.Protos" Version="0.105.2" />
<PackageReference Include="Momento.Protos" Version="0.106.0" />
<PackageReference Include="JWT" Version="9.0.3" />
<PackageReference Include="System.Threading.Channels" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
Expand Down

0 comments on commit 038b00d

Please sign in to comment.