Repository navigation
SOLR-9957: /export supports document transformers in fl - #5113
Conversation
* Parse fl with SolrReturnFields instead of splitting on commas, so transformers, their local params, and field aliases work * When fl has a transformer, collect each doc's fields into a SolrDocument, apply the transformer, and write the wanted fields; the plain path is unchanged * Transformer output is visible to the local streaming expression (expr) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Split the combined field-name set into two named sets, one for fetching transformer-read fields and one for deciding whether a non-exportable field errors or is skipped. No behavior change. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
dsmiley
left a comment
There was a problem hiding this comment.
This was basically a one-shot with Claude and I'm quite happy with the results. 2nd commit improves clarity around use of the confusing ReturnFields API.
| if (transformer == null) { | ||
| for (FieldWriter fieldWriter : writers) { | ||
| fieldWriter.write(sortDoc, context, ew); | ||
| } | ||
| return; | ||
| } |
There was a problem hiding this comment.
fast-path for previous logic, unchanged
| String[] fields = null; | ||
|
|
||
| if (fl == null) { | ||
| if (params.get(CommonParams.FL) == null) { |
There was a problem hiding this comment.
can you check this on the SolrReturnFields object? Just for brevity...
| Wildcard patterns can be used for the field list (e.g. `fl=*_i`) and will be expanded to the list of fields that match the pattern and are able to be exported, see <<Field Requirements>>. | ||
|
|
||
| Field aliases (e.g. `fl=id,price:price_d`) and xref:document-transformers.adoc[document transformers] (e.g. `fl=id,[docid]`) are supported, and their output is also visible to a local streaming expression. | ||
| Transformers are applied one document at a time, and those that depend on scores or on a list of matching documents won't work. |
There was a problem hiding this comment.
Generally transformers that don't return maps/lists/values won't work, right? I.e. fl=id,myquery:[subquery] won't work. The DocTransformer integration uncovers some gaps in the existing ExportWriter/javabin writer vs the text writer. It may not be a common use case here but maybe worth calling out.
| fieldWriter.write(sortDoc, context, ew); | ||
| fieldWriter.write(sortDoc, context, docWriter); | ||
| } | ||
| transformer.transform(doc, sortDoc.docBase + sortDoc.docId, DocIterationInfo.NONE); |
There was a problem hiding this comment.
Will this will return the transformed fields out of fl order? Not a huge deal but just pointing it out.
|
Looks cool, left some comments. I assume this is motivated by the highlighted stream work? |
|
thanks for the review; yes motivated by #5126 |
done
|
Albeit some might not work. Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
https://issues.apache.org/jira/browse/SOLR-9957
Description
/exportsilently ignored document transformers infl(e.g.[docid],[value],[explain]), and field aliases likefl=x:myfieldcame back under the original name.flwas also split naively on commas, so transformer local params containing commas broke.Solution
flwithSolrReturnFields(same as/select), so transformers, their local params, and aliases parse correctly.scoreis still rejected.flhas a transformer, each doc's fields are collected into aSolrDocument, the transformer is applied with the global docid, and the wanted fields are written out. Without a transformer, the existing streaming path is unchanged (no per-doc allocation).ResultContextwith the export's searcher, query and request. There is noDocList, so transformers needing one (or scores) aren't supported; this is documented.fl.expr).Behavior change:
fl=x:myfieldnow returnsxrather thanmyfield. Noted in the changelog.Tests
TestExportWriter.testDocTransformers:[docid]matches/select's, multi-valued fields survive, aliases and comma-containing local params work, transformer output reachesexpr, andscoreis still rejected.org.apache.solr.handler.export.*, plusStreamExpressionTest,StreamingTest,StreamDecoratorTest;./gradlew check -x test.🤖 This PR was written with Claude Code (AI-generated), directed and reviewed by the author.