You can avoid lots of problems by only fetching the data you really need. Already grouping the data in your query and doing the counts in there helps a lot.
To create such a response you can simply map your items to an array and convert that to JSON. You can use the collection methods to do that. Do note that the collection methods are amazing, they also are a bit slower with large data sets.
Fetching the correct data and then converting it is the best approach here.