<?xml version="1.0"?>
<oembed><version>1.0</version><provider_name>Aeologic Blog</provider_name><provider_url>https://www.aeologic.com/blog</provider_url><title>Transforming Result Documents - Ultimate Solr Guide - Aeologic Blog</title><type>rich</type><width>600</width><height>338</height><html>&lt;blockquote class="wp-embedded-content" data-secret="B1no2KugRH"&gt;&lt;a href="https://www.aeologic.com/blog/learning-to-rank19-transforming-result-documents/"&gt;Transforming Result Documents &#x2013; Ultimate Solr Guide&lt;/a&gt;&lt;/blockquote&gt;&lt;iframe sandbox="allow-scripts" security="restricted" src="https://www.aeologic.com/blog/learning-to-rank19-transforming-result-documents/embed/#?secret=B1no2KugRH" width="600" height="338" title="&#x201C;Transforming Result Documents &#x2013; Ultimate Solr Guide&#x201D; &#x2014; Aeologic Blog" data-secret="B1no2KugRH" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" class="wp-embedded-content"&gt;&lt;/iframe&gt;&lt;script&gt;
/*! This file is auto-generated */
!function(d,l){"use strict";l.querySelector&amp;&amp;d.addEventListener&amp;&amp;"undefined"!=typeof URL&amp;&amp;(d.wp=d.wp||{},d.wp.receiveEmbedMessage||(d.wp.receiveEmbedMessage=function(e){var t=e.data;if((t||t.secret||t.message||t.value)&amp;&amp;!/[^a-zA-Z0-9]/.test(t.secret)){for(var s,r,n,a=l.querySelectorAll('iframe[data-secret="'+t.secret+'"]'),o=l.querySelectorAll('blockquote[data-secret="'+t.secret+'"]'),c=new RegExp("^https?:$","i"),i=0;i&lt;o.length;i++)o[i].style.display="none";for(i=0;i&lt;a.length;i++)s=a[i],e.source===s.contentWindow&amp;&amp;(s.removeAttribute("style"),"height"===t.message?(1e3&lt;(r=parseInt(t.value,10))?r=1e3:~~r&lt;200&amp;&amp;(r=200),s.height=r):"link"===t.message&amp;&amp;(r=new URL(s.getAttribute("src")),n=new URL(t.value),c.test(n.protocol))&amp;&amp;n.host===r.host&amp;&amp;l.activeElement===s&amp;&amp;(d.top.location.href=t.value))}},d.addEventListener("message",d.wp.receiveEmbedMessage,!1),l.addEventListener("DOMContentLoaded",function(){for(var e,t,s=l.querySelectorAll("iframe.wp-embedded-content"),r=0;r&lt;s.length;r++)(t=(e=s[r]).getAttribute("data-secret"))||(t=Math.random().toString(36).substring(2,12),e.src+="#?secret="+t,e.setAttribute("data-secret",t)),e.contentWindow.postMessage({message:"ready",secret:t},"*")},!1)))}(window,document);
//# sourceURL=https://www.aeologic.com/blog/wp-includes/js/wp-embed.min.js
&lt;/script&gt;
</html><thumbnail_url>https://www.aeologic.com/blog/wp-content/uploads/2020/06/Transforming-Result-Documents-in-solr-1.png</thumbnail_url><thumbnail_width>1080</thumbnail_width><thumbnail_height>622</thumbnail_height><description>Document Transformers modify the information returned about documents in the results of a query. Using Document Transformers When executing a request, a document transformer can be used by including it in the&nbsp;fl&nbsp;parameter using square brackets, for example: fl=id,name,score,[shard] Some transformers allow, or require, local parameters which can be specified as key value pairs inside the brackets: fl=id,name,score,[explain style=nl] As with regular fields, you can change the key used when a Transformer adds a field to a document via a prefix: fl=id,name,score,my_val_a:[value v=42 t=int],my_val_b:[value v=7 t=float] The sections below discuss exactly what these various transformers do. Available Transformers [value] &#x2013; ValueAugmenterFactory Modifies every document to include the exact same value, as if it were a stored field in every document: q=*:*&amp;fl=id,greeting:[value v='hello']&amp;wt=xml The above query would produce results like the following: &lt;result name="response" numFound="32" start="0"&gt; &lt;doc&gt; &lt;str name="id"&gt;1&lt;/str&gt; &lt;str name="greeting"&gt;hello&lt;/str&gt;&lt;/doc&gt; &lt;/doc&gt; ... By default, values are returned as a String, but a&nbsp;t&nbsp;parameter can be specified using a value of&nbsp;int,&nbsp;float,&nbsp;double, or&nbsp;date&nbsp;to force a specific return type: q=*:*&amp;fl=id,my_number:[value v=42 t=int],my_string:[value v=42] In addition to using these request parameters, you can configure additional named instances of ValueAugmenterFactory, or override the default behavior of the existing&nbsp;[value]&nbsp;transformer in your&nbsp;solrconfig.xml&nbsp;file: &lt;transformer name="mytrans2" class="org.apache.solr.response.transform.ValueAugmenterFactory" &gt; &lt;int name="value"&gt;5&lt;/int&gt; &lt;/transformer&gt; &lt;transformer name="value" class="org.apache.solr.response.transform.ValueAugmenterFactory" &gt; &lt;double name="defaultValue"&gt;5&lt;/double&gt; &lt;/transformer&gt; The&nbsp;value&nbsp;option forces an explicit value to always be used, while the&nbsp;defaultValue&nbsp;option provides a default that can still be overridden using the&nbsp;v&nbsp;and&nbsp;t&nbsp;local parameters. [explain] &#x2013; ExplainAugmenterFactory Augments each document with an inline explanation of its score exactly like the information available about each document in the debug section: q=features:cache&amp;fl=id,[explain style=nl] Supported values for&nbsp;style&nbsp;are&nbsp;text,&nbsp;html, and&nbsp;nl&nbsp;which returns the information as structured data. Here is the output of the above request using&nbsp;style=nl: { "response":{"numFound":2,"start":0,"docs":[ { "id":"6H500F0", "[explain]":{ "match":true, "value":1.052226, "description":"weight(features:cache in 2) [DefaultSimilarity], result of:", "details":[{ }]}}]}} A default style can be configured by specifying an&nbsp;args&nbsp;parameter in your&nbsp;solrconfig.xml&nbsp;configuration: &lt;transformer name="explain" class="org.apache.solr.response.transform.ExplainAugmenterFactory" &gt; &lt;str name="args"&gt;nl&lt;/str&gt; &lt;/transformer&gt; [child] &#x2013; ChildDocTransformerFactory This transformer returns all&nbsp;descendant documents&nbsp;of each parent document matching your query in a flat list nested inside the matching parent document. This is useful when you have indexed nested child documents and want to retrieve the child documents for the relevant parent documents for any type of search query. fl=id,[child parentFilter=doc_type:book childFilter=doc_type:chapter limit=100] Note that this transformer can be used even though the query itself is not a&nbsp;Block Join query. When using this transformer, the&nbsp;parentFilter&nbsp;parameter must be specified&nbsp;unless&nbsp;the schema declares&nbsp;_nest_path_. It works the same as in all Block Join Queries. Additional optional parameters are:childFilterA query to filter which child documents should be included. This can be particularly useful when you have multiple levels of hierarchical documents. The default is all children. This query supports a special syntax to match nested doc patterns so long as&nbsp;_nest_path_&nbsp;is defined in the schema and the query contains a&nbsp;/&nbsp;preceding the first&nbsp;:. Example:&nbsp;childFilter=/comments/content:recipe&nbsp;Further details of this are experimental.limitThe maximum number of child documents to be returned per parent document. The default is&nbsp;10.fl The field list which the transformer is to return. The default is the top level&nbsp;fl). There is a further limitation in which the fields here should be a subset of those specified by the top level&nbsp;fl&nbsp;parameter. [shard] &#x2013; ShardAugmenterFactory This transformer adds information about what shard each individual document came from in a distributed request. ShardAugmenterFactory does not support any request parameters, or configuration options. [docid] &#x2013; DocIdAugmenterFactory This transformer adds the internal Lucene document id to each document &#x2013; this is primarily only useful for debugging purposes. DocIdAugmenterFactory does not support any request parameters, or configuration options. [elevated] and [excluded] These transformers are available only when using the&nbsp;Query Elevation Component. [elevated]&nbsp;annotates each document to indicate if it was elevated or not. [excluded]&nbsp;annotates each document to indicate if it would have been excluded &#x2013; this is only supported if you also use the&nbsp;markExcludes&nbsp;parameter. fl=id,[elevated],[excluded]&amp;excludeIds=GB18030TEST&amp;elevateIds=6H500F0&amp;markExcludes=true { "response":{"numFound":32,"start":0,"docs":[ { "id":"6H500F0", "[elevated]":true, "[excluded]":false}, { "id":"GB18030TEST", "[elevated]":false, "[excluded]":true}, { "id":"SP2514N", "[elevated]":false, "[excluded]":false}, ]}} [json] / [xml] These transformers replace a field value containing a string representation of a valid XML or JSON structure with the actual raw XML or JSON structure instead of just the string value. Each applies only to the specific writer, such that&nbsp;[json]&nbsp;only applies to&nbsp;wt=json&nbsp;and&nbsp;[xml]&nbsp;only applies to&nbsp;wt=xml. fl=id,source_s:[json]&amp;wt=json [subquery] This transformer executes a separate query per transforming document passing document fields as an input for subquery parameters. It&#x2019;s usually used with&nbsp;{!join}&nbsp;and&nbsp;{!parent}&nbsp;query parsers, and is intended to be an improvement for&nbsp;[child]. It must be given an unique name:&nbsp;fl=*,children:[subquery] There might be a few of them, e.g.,&nbsp;fl=*,sons:[subquery],daughters:[subquery]. Every&nbsp;[subquery]&nbsp;occurrence adds a field into a result document with the given name, the value of this field is a document list, which is a result of executing subquery using document fields as an input. Subquery will use the&nbsp;/select&nbsp;search handler by default, and will return an error if&nbsp;/select&nbsp;is not configured. This can be changed by supplying&nbsp;foo.qt&nbsp;parameter. Here is how it looks like using various formats:XML &lt;result name="response" numFound="2" start="0"&gt; &lt;doc&gt; &lt;int name="id"&gt;1&lt;/int&gt; &lt;arr name="title"&gt; &lt;str&gt;vdczoypirs&lt;/str&gt; &lt;/arr&gt; &lt;result name="children" numFound="1" start="0"&gt; &lt;doc&gt; &lt;int name="id"&gt;2&lt;/int&gt; &lt;arr name="title"&gt; &lt;str&gt;vdczoypirs&lt;/str&gt; &lt;/arr&gt; &lt;/doc&gt; &lt;/result&gt; &lt;/doc&gt; ... JSON { "response":{ "numFound":2, "start":0, "docs":[ { "id":1, "subject":["parentDocument"], "title":["xrxvomgu"], "children":{ "numFound":1, "start":0, "docs":[ { "id":2, "cat":["childDocument"] } ] }}]}} SolrJ SolrDocumentList subResults = (SolrDocumentList)doc.getFieldValue("children"); Subquery Result Fields To appear in subquery document list, a field should be specified in both&nbsp;fl&nbsp;parameters: in the main&nbsp;fl&nbsp;(despite the main result documents have no this field), and in subquery&#x2019;s&nbsp;fl&nbsp;(e.g.,&nbsp;foo.fl). Wildcards can be used in one or both of these parameters. For example, if field&nbsp;title&nbsp;should appear in categories subquery, it can be done via one of these ways: fl=...title,categories:[subquery]&amp;categories.fl=title&amp;categories.q=... fl=...title,categories:[subquery]&amp;categories.fl=*&amp;categories.q=... fl=...*,categories:[subquery]&amp;categories.fl=title&amp;categories.q=... fl=...*,categories:[subquery]&amp;categories.fl=*&amp;categories.q=... Subquery Parameters Shift If a subquery is declared as&nbsp;fl=*,foo:[subquery], subquery parameters are prefixed with the given name and period. For example: q=*:*&amp;fl=*,**foo**:[subquery]&amp;**foo.**q=to be continued&amp;**foo.**rows=10&amp;**foo.**sort=id desc Document Field as an Input for Subquery Parameters It&#x2019;s necessary to pass some document field values as a parameter for subquery. It&#x2019;s supported via an implicit&nbsp;row.fieldname&nbsp;parameter, and can be (but might not only) referred via local parameters syntax: q=name:john&amp;fl=name,id,depts:[subquery]&amp;depts.q={!terms f=id v=$row.dept_id}&amp;depts.rows=10 Here departments are retrieved per every employee in search result. We can say that it&#x2019;s like SQL&nbsp;join ON emp.dept_id=dept.id. Note, when a document field has [&hellip;]</description></oembed>
