-
Notifications
You must be signed in to change notification settings - Fork 13
Description
The issue
When using Product Search with a Stats Facet, the return value in the response only contains the name of the facet and none of the data.
Example facet:
new ProductSearchFacetStatsExpression() { Stats = new ProductSearchFacetStatsValue() { Name = FacetName, Field = CtField } };
The return value is of type ProductSearchFacetResult, which only contains a facet name, instead of the expected ProductSearchFacetResultStats. On debugging the issue I found that there seems to be a missing case in ProductSearchFacetConverter since it does not seem to have any path that returns a Stat result.
Overriding this converter in the SDK requires reflection on private implementation fields which is not a sustainable method:
var serializerService = (SerializerService)services.GetRequiredService<IApiSerializerService>();
var fieldInfo = typeof(SerializerService).GetField("_serializerOptions", BindingFlags.NonPublic | BindingFlags.Instance);
var objectValue = fieldInfo!.GetValue(serializerService);
var serializerOptions = objectValue as JsonSerializerOptions;
var index = serializerOptions!.Converters.Index().First(x => x.Item is ProductSearchFacetConverter).Index;
serializerOptions.Converters.RemoveAt(index);
// Order matters so insert at same index as removed converter!
serializerOptions!.Converters.Insert(index, new ProductSearchFacetConverterWithStat(serializerService));
The response contains the correct Stats data (observed by adding middleware, and also by debugging the ProductSearchFacetConverter) so an update to the converter should be sufficient. An implementation that only handles the number version of Stats could be an addition like this:
if (rootElement.TryGetProperty("min", out var minElement)
&& rootElement.TryGetProperty("max", out var maxElement)
&& rootElement.TryGetProperty("mean", out var meanElement)
&& rootElement.TryGetProperty("sum", out var sumElement)
&& rootElement.TryGetProperty("count", out var countElement))
return new ProductSearchFacetResultStats()
{
Name = nameProp.GetString(),
Min = minElement.GetDecimal(),
Max = maxElement.GetDecimal(),
Mean = meanElement.GetDecimal(),
Sum = sumElement.GetDecimal(),
Count = countElement.GetInt64(),
};
I would however expect it to handle the DateTime case as well (and also take into account which fields are actually required).