Fetching the total number of products inside Parent Category

We want to display the total number of products inside a Parent Category(i.e. the sum of total number of products inside each sub category), so we are currently using the listEntries API in catalog module with this payload

{
  "objectType" : "CatalogProduct",
"searchInChildren" : true,
"categoryId" : "846b4e76-f61b-4b10-9971-b6d92ad60b44",
"take" : 0
}

We are calling this for each Category(which might be a parentCategory) inside Catalog, is there any other optimised solution for this?

The best way to achive it is using Full text search and facets for outlines:

Virto Storefront use it:

Thanks @OlegoO.
There is another issue I am facing. I wish to extend CategoryItemRelation table but when I try to do so I am facing conversion issues for CategoryLink. I am doing this for enabling/disabling linked virtual products by adding a IsVirtualItemActive field in CategoryItemRelation. In platform it is fetching the products correctly, but it is not able to display the virtual categories, it throws this error
Unable to cast object of type 'VirtoCommerce.CatalogModule.Core.Model.CategoryLink' to type 'Virto.CustomCatalogModule.Core.Models.ExtendedCategoryLink'.

Can you please help me in figuring out the issue?

Could you attach the complete error message with stack?

I debugged it, listEntries is building the correct result and returning it from dotnet application, but after that instead of response it is throwing this exception.

VirtoCommerce.Platform.Web.Middleware.ApiErrorWrappingMiddleware[0]
      Unable to cast object of type 'VirtoCommerce.CatalogModule.Core.Model.CategoryLink' to type 'Virto.CustomCatalogModule.Core.Models.ExtendedCategoryLink'.
      Newtonsoft.Json.JsonSerializationException: Error getting value from 'IsItemRelationActive' on 'VirtoCommerce.CatalogModule.Core.Model.CategoryLink'.
       ---> System.InvalidCastException: Unable to cast object of type 'VirtoCommerce.CatalogModule.Core.Model.CategoryLink' to type 'Virto.CustomCatalogModule.Core.Models.ExtendedCategoryLink'.
         at lambda_method3284(Closure , Object )
         at Newtonsoft.Json.Serialization.ExpressionValueProvider.GetValue(Object target)
         --- End of inner exception stack trace ---
         at Newtonsoft.Json.Serialization.ExpressionValueProvider.GetValue(Object target)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues(JsonWriter writer, Object value, JsonContainerContract contract, JsonProperty member, JsonProperty property, JsonContract& memberContract, Object& memberValue)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)
         at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)
         at Microsoft.AspNetCore.Mvc.Formatters.NewtonsoftJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
         at Microsoft.AspNetCore.Mvc.Formatters.NewtonsoftJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
         at Microsoft.AspNetCore.Mvc.Formatters.NewtonsoftJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeResultAsync>g__Logged|22_0(ResourceInvoker invoker, IActionResult result)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|30_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
      --- End of stack trace from previous location ---
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
         at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
         at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)
         at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
         at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
         at VirtoCommerce.Platform.Web.Middleware.ApiErrorWrappingMiddleware.Invoke(HttpContext context) in /home/runner/work/vc-platform/vc-platform/src/VirtoCommerce.Platform.Web/Middleware/ApiErrorWrappingMiddleware.cs:line 52
1 Like