The sort-first-then-resolve-Strings is what I did in the proof of concept. The speed is that of TermsInfoReader, where it delivers a Term from a given position. If this is too slow for multiple segments, the segment-spanning ordered ordinals-approach could be tried.
As for deprecating stored fields, then I guess there's the issue of spatial locality. Wouldn't moving the bytes into the inverted term index bloat it in a way that makes all searches slower?
There's an issue of having multiple terms in the same field for a given document, which also ties into facets. It takes some more logic to handle this, but I think it can be done without excessive memory or processing load: Basically we make two passes, where the first pass determines the optimal packed structure and the second pass fills in the ordinals. This would give us a memory overhead of
#docs + #references_to_terms + #terms ints
for very fast facet structure building with support for collator sorted terms in the facet result. This is basically what we're already doing at Statsbiblioteket - the only real difference is whether the Strings are pulled from the Terms index or from an external structure.
Saving RAM, this could be be done using PackedInts
#docs*log2(#references_to_terms) + #references_to_terms*log2(#terms) + #terms*log2(#terms) bits
but I am afraid that access time would suffer. A hybrid
#docs*32 + #references_to_terms*32 + #terms*log2(#terms) bits
would be just as fast for building as the non-packed version and a wee bit slower for the final fetching of the terms.
Of course, just as with fillFields=true searches, the calculated Terms must be extracted at the end. For faceting, this can be quite a load.
The facet-supporting structure is not as simple as the sorting-optimized one. I realize that supporting facets from the start might be quite a large jump. However, if API-breaks are requires, I guess it would be best to do it as few times as possible?