After thinking over your comments, I removed the facetHandler completely, instead loading the Facets into a plain user cache, and put the output work in a utils class similar to SolrPluginUtils. It complicates the Term caching for me slightly, but it allows me to add a "FacetUtils.doStandardFaceting(req, query, results);" type of call to any requestHandler without any changes to Solr internals. Thank you for pointing me in that general direction.
On your comment about searcherNumDocs() and valueDocSet.intersectionSize() being essentially equivalent, I found I could do the job with either, but noted two differences that may be obvious, but may be worth documenting explicitly for people developing faceting: - Since valueDocSet.intersectionSize(otherSet) compares the actual result set. the requestHandler needs to get a full (or at least larger) set before limiting it by req.getStart() and req.getLimit(), or you only calculate the facets against that one page. Then, after you calculate the facets, you can use subset() to restrict the range for output. - searcher.numDocs(resultQuery, facetQuery) does not require any subset steps, but, since it uses the Query, not the end DocList, it does not know about any filter queries applied to the request. The facet intersection will therefore be calculated against documents that are not returned in the base results NamedList. Thanks, Greg