{"id":814,"date":"2020-04-18T05:44:18","date_gmt":"2020-04-18T05:44:18","guid":{"rendered":"https:\/\/www.aeologic.com\/blog\/?p=814"},"modified":"2020-04-18T05:44:18","modified_gmt":"2020-04-18T05:44:18","slug":"indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide","status":"publish","type":"post","link":"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/","title":{"rendered":"Indexing and Searching Nested Documents in Solr &#8211; Ultimate Solr Guide"},"content":{"rendered":"<p>Hi All, Today I will be writing about another important aspect of Solr that encapsulates the need of a lot of business applications. Suppose we need to index data of an e-commerce company that wants to host a variety of products on their websites along with associated SKU&#8217;s. This data needs to be indexed, updated, searched upon in a way that is legible to both the end-users and the merchandisers. So, a natural question arises, how to represent this data? Also, what matrix to follow in order to maintain the data easily and effectively?<\/p>\n<p>To address this problem, Solr provides us with a mechanism to associate multiple docs with each other and put them in a relationship. Also, it provides both indexing and searching mechanisms to get data in and out. What we are referring to here is called a &#8220;Nested document structure&#8221;, or more technically, a BLOCK in Solr. Put simply, a block is a set of parent-child relation between multiple documents.<\/p>\n<p>Let&#8217;s understand this in two parts.<\/p>\n<h1><strong>Indexing Nested Documents<\/strong><\/h1>\n<p>Let&#8217;s assume a nested structure as below:<\/p>\n<p>{<br \/>\n&#8220;id&#8221;:&#8221;100&#8243;,<br \/>\n&#8220;scope_ss&#8221;:&#8221;product&#8221;,<br \/>\n&#8220;category_ss&#8221;:&#8221;OutdoorSofa&#8221;,<br \/>\n&#8220;productType_ss&#8221;:&#8221;sofa&#8221;,<br \/>\n&#8220;<strong>_childDocuments_<\/strong>&#8220;: [<br \/>\n{<br \/>\n&#8220;id&#8221;:&#8221;101&#8243;,<br \/>\n&#8220;scope_ss&#8221;:&#8221;sku&#8221;,<br \/>\n&#8220;Fabric_ss&#8221;:&#8221;Polyester&#8221;,<br \/>\n&#8220;Depth_ss&#8221;:&#8221;Classic&#8221;,<br \/>\n&#8220;Finish_ss&#8221; : &#8220;Fine&#8221;,<br \/>\n&#8220;Color_ss&#8221;:&#8221;Grey&#8221;},<br \/>\n{<br \/>\n&#8220;id&#8221;:&#8221;102&#8243;,<br \/>\n&#8220;scope_ss&#8221;:&#8221;sku&#8221;,<br \/>\n&#8220;Fabric_ss&#8221;:&#8221;nylon&#8221;,<br \/>\n&#8220;Depth_ss&#8221;:&#8221;Petite&#8221;,<br \/>\n&#8220;Finish_ss&#8221; : &#8220;Grey&#8221;,<br \/>\n&#8220;Color_ss&#8221;:&#8221;Green&#8221;},<br \/>\n{<br \/>\n&#8220;id&#8221;:&#8221;103&#8243;,<br \/>\n&#8220;scope_ss&#8221;:&#8221;sku&#8221;,<br \/>\n&#8220;Fabric_ss&#8221;:&#8221;acrylic&#8221;,<br \/>\n&#8220;Depth_ss&#8221;:&#8221;Petite&#8221;,<br \/>\n&#8220;Finish_ss&#8221; : &#8220;Espresso&#8221;,<br \/>\n&#8220;Color_ss&#8221;:&#8221;Green&#8221;},<br \/>\n{<br \/>\n&#8220;id&#8221;:&#8221;104&#8243;,<br \/>\n&#8220;scope_ss&#8221;:&#8221;sku&#8221;,<br \/>\n&#8220;Fabric_ss&#8221;:&#8221;Polyester&#8221;,<br \/>\n&#8220;Depth_ss&#8221;: &#8220;Classic&#8221;,<br \/>\n&#8220;Finish_ss&#8221; : &#8220;Grey&#8221;,<br \/>\n&#8220;Color_ss&#8221;:&#8221;Dove&#8221;},<\/p>\n<p>{&#8220;id&#8221;:&#8221;105&#8243;,<br \/>\n&#8220;scope_ss&#8221;:&#8221;sku&#8221;,<br \/>\n&#8220;Fabric_ss&#8221;:&#8221;nylon&#8221;,<br \/>\n&#8220;Depth_ss&#8221;: &#8220;Classic&#8221;,<br \/>\n&#8220;Finish_ss&#8221; : &#8220;Grey&#8221;,<br \/>\n&#8220;Color_ss&#8221;:&#8221;Blue&#8221;}]<\/p>\n<p>}<\/p>\n<p><strong>_childDocuments_\u00a0<\/strong>tells solr that each object defined within the scope is a child to the doc it belongs to. In essence, we have just created a block of information that has properties for SKU&#8217;s which imparts some meaning to the application scenarios. Now let&#8217;s see how we can index the doc. Utilizing Solr&#8217;s dynamic schema mapping capabilities, we can be certain that all the fields in the document will get indexed and get reflected (Notice <strong>_ss <\/strong>in fields, they are stored as String array). Now, one may ask upon careful observation that why the data type used is array when the field is storing String type information. Answer to this question lies in more subtle understanding of inner working of Solr.<\/p>\n<p>When Solr indexes a nested document, it stores all field values for a field in a set. This effectively means each field has multiple values and hence the type, array of String. If one tries to index data without using _ss or just _s (String type in Solr), solr engine throws an error. Now, assuming we have settled with basics, let&#8217;s continue to index the data.<\/p>\n<p>Fire up UI and index data by navigating to necessary modalities as below:<\/p>\n<p><img fetchpriority=\"high\" decoding=\"async\" class=\"alignnone wp-image-815\" src=\"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/Solr_doc.png\" alt=\"\" width=\"682\" height=\"608\" srcset=\"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/Solr_doc.png 829w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/Solr_doc-300x267.png 300w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/Solr_doc-768x685.png 768w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/Solr_doc-505x450.png 505w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/Solr_doc-260x232.png 260w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/Solr_doc-90x80.png 90w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/Solr_doc-213x190.png 213w\" sizes=\"(max-width: 682px) 100vw, 682px\" \/><\/p>\n<p>Paste the JSON doc in &#8220;Documents(s)&#8221; section and index the document. If all configuration is proper, then, the index upon querying will appear as below:<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-826\" src=\"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/index.png\" alt=\"\" width=\"394\" height=\"875\" srcset=\"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/index.png 394w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/index-135x300.png 135w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/index-203x450.png 203w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/index-117x260.png 117w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/index-36x80.png 36w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/index-86x190.png 86w\" sizes=\"(max-width: 394px) 100vw, 394px\" \/><\/p>\n<p><strong>Note:<\/strong> Notice how the parent doc (the product information) is referenced at bottom and child docs are piled upon it. This is not by accident but by design.<\/p>\n<h1><strong>Querying Nested Documents<\/strong><\/h1>\n<p>Let&#8217;s dive into basics of querying nested docs in Solr.<\/p>\n<p>One of the most needed use-case in context of e-commerce data-set is Faceting. Faceting for nested docs by design is different than traditional docs in Solr.<\/p>\n<ul>\n<li>To understand this, let&#8217;s generate facets for Color_ss and Fabric_ss fields.\n<ul>\n<li><strong>Query Syntax<\/strong>: &amp;json.facet={Fabrics:{type:terms,field:<strong>Fabric_ss<\/strong>,limit:-1},Colors:{type:terms,field:<strong>Color_ss<\/strong>,limit:-1}}&amp;rows=0<\/li>\n<li><strong>Response<\/strong>:<img decoding=\"async\" class=\"alignnone size-full wp-image-828\" src=\"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/color_fabric_response.png\" alt=\"\" width=\"982\" height=\"581\" srcset=\"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/color_fabric_response.png 982w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/color_fabric_response-300x177.png 300w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/color_fabric_response-768x454.png 768w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/color_fabric_response-720x426.png 720w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/color_fabric_response-260x154.png 260w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/color_fabric_response-135x80.png 135w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/color_fabric_response-250x148.png 250w\" sizes=\"(max-width: 982px) 100vw, 982px\" \/><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>If one observes carefully, one can see clearly how two buckets for each of the fields is formed. First bucket for Fabrics and second bucket for colors. Its worth mentioning here that the name, &#8220;Fabrics&#8221; and &#8220;Colors&#8221; are custom headers and can be changed at will.<\/p>\n<ul>\n<li>Lets try something else. Let&#8217;s try nested faceting here.\n<ul>\n<li><strong>Query<\/strong>: &amp;json.facet={Fabrics:{type:terms,field:Fabric_ss,limit:-1,facet:{Colors:{type:terms,field:Color_ss,limit:-1}}}}&amp;rows=0<\/li>\n<li><strong>Response<\/strong>:<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-830\" src=\"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/nested_facet.png\" alt=\"\" width=\"1049\" height=\"659\" srcset=\"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/nested_facet.png 1049w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/nested_facet-300x188.png 300w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/nested_facet-1024x643.png 1024w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/nested_facet-768x482.png 768w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/nested_facet-716x450.png 716w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/nested_facet-260x163.png 260w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/nested_facet-127x80.png 127w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/nested_facet-250x157.png 250w\" sizes=\"(max-width: 1049px) 100vw, 1049px\" \/><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Here, we have a bucket called &#8220;Fabrics&#8221; and nested within it is another bucket called &#8220;Colors&#8221;. In essence, we are presented with more granular information telling the color of each fabric type.<\/p>\n<p>Let&#8217;s try another interesting query, one combining nested faceting with independent buckets.<\/p>\n<ul>\n<li><strong>Query<\/strong>: &amp;json.facet={Depth:{type:terms,field:Depth_ss,limit:-1},Fabrics:{type:terms,field:Fabric_ss,limit:-1,facet:{Colors:{type:terms,field:Color_ss,limit:-1}}}}&amp;rows=0<\/li>\n<li><strong>Response:<\/strong>\u00a0<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-832\" src=\"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/nested_facet_independent.png\" alt=\"\" width=\"1414\" height=\"755\" srcset=\"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/nested_facet_independent.png 1414w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/nested_facet_independent-300x160.png 300w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/nested_facet_independent-1024x547.png 1024w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/nested_facet_independent-768x410.png 768w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/nested_facet_independent-720x384.png 720w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/nested_facet_independent-1180x630.png 1180w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/nested_facet_independent-260x139.png 260w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/nested_facet_independent-150x80.png 150w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/nested_facet_independent-250x133.png 250w\" sizes=\"(max-width: 1414px) 100vw, 1414px\" \/><\/li>\n<\/ul>\n<p>Here, as one observes carefully, one bucket stands for independent Depth and other stands for nested facet for Fabric with Color. This enables businesses using Solr to present product information at a granular level for their customers.<\/p>\n<p>Some other useful queries include:<\/p>\n<ul>\n<li>To view all products and SKU information:\n<ul>\n<li><strong>Query:<\/strong> q=*:*&amp;rows=10<\/li>\n<li><strong>Response:<\/strong>\n<ul>\n<li><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-833\" src=\"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/all.png\" alt=\"\" width=\"398\" height=\"893\" srcset=\"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/all.png 398w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/all-134x300.png 134w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/all-201x450.png 201w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/all-116x260.png 116w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/all-36x80.png 36w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/all-85x190.png 85w\" sizes=\"(max-width: 398px) 100vw, 398px\" \/><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li>To fetch specific products and its associated SKUs:\n<ul>\n<li><strong>Query<\/strong>: q={!child%20of=&#8221;scope_ss:product&#8221;}id:100&amp;wt=json<\/li>\n<li><strong>Response:<\/strong><\/li>\n<li><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-834\" src=\"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/specific_product.png\" alt=\"\" width=\"442\" height=\"796\" srcset=\"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/specific_product.png 442w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/specific_product-167x300.png 167w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/specific_product-250x450.png 250w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/specific_product-144x260.png 144w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/specific_product-44x80.png 44w, https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/specific_product-106x190.png 106w\" sizes=\"(max-width: 442px) 100vw, 442px\" \/><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><strong>{!child%20of=&#8221;scope_ss:product&#8221;}<\/strong> &#8211; This filter fetches information for all parent products by using the unique field-value pair used to identify a parent doc in index.<\/p>\n<p><strong>id:100 &#8211; <\/strong>This filter fetches &#8220;some&#8221; parents based on a specific field-value pair for a parent doc.<\/p>\n<h1>Updating a nested document in Solr<\/h1>\n<p>Updating a nested document in Solr involves is a very tricky business. One has to update a complete BLOCK if a single SKU has to be updated or a new SKU has to be added. (<strong>THIS IS THE ONLY LIMITATION OF SOLR<\/strong>). This essentially happens because of underlying Lucene handlers. Exact explanation for this, though present, is beyond the scope of this post.<\/p>\n<h1>Deleting a SKU\/child document<\/h1>\n<p>The solr document is a little ambiguous about it though based on a simple POC, its clear that one can remove a child doc from solr by using a simple delete by ID API. One can invoke update handler for core\/collection as below:<\/p>\n<p><strong>Query:<\/strong> update?stream.body=&lt;delete&gt;&lt;query&gt;<strong>id:101&lt;<\/strong>\/query&gt;&lt;\/delete&gt;&amp;commit=true<\/p>\n<p><strong>Response:\u00a0<\/strong> This removes the child document with id:101 from index<\/p>\n<p>So, that&#8217;s it for today. Will be back with another interesting post on Solr.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hi All, Today I will be writing about another important aspect of Solr that encapsulates the need of a lot of business applications. Suppose we need to index data of an e-commerce company that wants to host a variety of products on their websites along with associated SKU&#8217;s. This data needs to be indexed, updated, searched upon in a way that is legible to both the end-users and the merchandisers. So, a natural question arises, how to represent this data? Also, what matrix to follow in order to maintain the data easily and effectively? To address this problem, Solr provides us with a mechanism to associate multiple docs with each other and put them in a relationship. Also, it provides both indexing and searching mechanisms to get data in and out. What we are referring to here is called a &#8220;Nested document structure&#8221;, or more technically, a BLOCK in Solr. Put simply, a block is a set of parent-child relation between multiple documents. Let&#8217;s understand this in two parts. Indexing Nested Documents Let&#8217;s assume a nested structure as below: { &#8220;id&#8221;:&#8221;100&#8243;, &#8220;scope_ss&#8221;:&#8221;product&#8221;, &#8220;category_ss&#8221;:&#8221;OutdoorSofa&#8221;, &#8220;productType_ss&#8221;:&#8221;sofa&#8221;, &#8220;_childDocuments_&#8220;: [ { &#8220;id&#8221;:&#8221;101&#8243;, &#8220;scope_ss&#8221;:&#8221;sku&#8221;, &#8220;Fabric_ss&#8221;:&#8221;Polyester&#8221;, &#8220;Depth_ss&#8221;:&#8221;Classic&#8221;, &#8220;Finish_ss&#8221; : &#8220;Fine&#8221;, &#8220;Color_ss&#8221;:&#8221;Grey&#8221;}, { &#8220;id&#8221;:&#8221;102&#8243;, &#8220;scope_ss&#8221;:&#8221;sku&#8221;, &#8220;Fabric_ss&#8221;:&#8221;nylon&#8221;, &#8220;Depth_ss&#8221;:&#8221;Petite&#8221;, &#8220;Finish_ss&#8221; : &#8220;Grey&#8221;, &#8220;Color_ss&#8221;:&#8221;Green&#8221;}, { &#8220;id&#8221;:&#8221;103&#8243;, &#8220;scope_ss&#8221;:&#8221;sku&#8221;, &#8220;Fabric_ss&#8221;:&#8221;acrylic&#8221;, &#8220;Depth_ss&#8221;:&#8221;Petite&#8221;, &#8220;Finish_ss&#8221; : &#8220;Espresso&#8221;, &#8220;Color_ss&#8221;:&#8221;Green&#8221;}, { &#8220;id&#8221;:&#8221;104&#8243;, &#8220;scope_ss&#8221;:&#8221;sku&#8221;, &#8220;Fabric_ss&#8221;:&#8221;Polyester&#8221;, &#8220;Depth_ss&#8221;: &#8220;Classic&#8221;, &#8220;Finish_ss&#8221; : &#8220;Grey&#8221;, &#8220;Color_ss&#8221;:&#8221;Dove&#8221;}, {&#8220;id&#8221;:&#8221;105&#8243;, &#8220;scope_ss&#8221;:&#8221;sku&#8221;, &#8220;Fabric_ss&#8221;:&#8221;nylon&#8221;, &#8220;Depth_ss&#8221;: &#8220;Classic&#8221;, &#8220;Finish_ss&#8221; : &#8220;Grey&#8221;, &#8220;Color_ss&#8221;:&#8221;Blue&#8221;}] } _childDocuments_\u00a0tells solr that each object defined within the scope is a child to the doc it belongs to. In essence, we have just created a block of information that has properties for SKU&#8217;s which imparts some meaning to the application scenarios. Now let&#8217;s see how we can index the doc. Utilizing Solr&#8217;s dynamic schema mapping capabilities, we can be certain that all the fields in the document will get indexed and get reflected (Notice _ss in fields, they are stored as String array). Now, one may ask upon careful observation that why the data type used is array when the field is storing String type information. Answer to this question lies in more subtle understanding of inner working of Solr. When Solr indexes a nested document, it stores all field values for a field in a set. This effectively means each field has multiple values and hence the type, array of String. If one tries to index data without using _ss or just _s (String type in Solr), solr engine throws an error. Now, assuming we have settled with basics, let&#8217;s continue to index the data. Fire up UI and index data by navigating to necessary modalities as below: Paste the JSON doc in &#8220;Documents(s)&#8221; section and index the document. If all configuration is proper, then, the index upon querying will appear as below: Note: Notice how the parent doc (the product information) is referenced at bottom and child docs are piled upon it. This is not by accident but by design. Querying Nested Documents Let&#8217;s dive into basics of querying nested docs in Solr. One of the most needed use-case in context of e-commerce data-set is Faceting. Faceting for nested docs by design is different than traditional docs in Solr. To understand this, let&#8217;s generate facets for Color_ss and Fabric_ss fields. Query Syntax: &amp;json.facet={Fabrics:{type:terms,field:Fabric_ss,limit:-1},Colors:{type:terms,field:Color_ss,limit:-1}}&amp;rows=0 Response: If one observes carefully, one can see clearly how two buckets for each of the fields is formed. First bucket for Fabrics and second bucket for colors. Its worth mentioning here that the name, &#8220;Fabrics&#8221; and &#8220;Colors&#8221; are custom headers and can be changed at will. Lets try something else. Let&#8217;s try nested faceting here. Query: &amp;json.facet={Fabrics:{type:terms,field:Fabric_ss,limit:-1,facet:{Colors:{type:terms,field:Color_ss,limit:-1}}}}&amp;rows=0 Response: Here, we have a bucket called &#8220;Fabrics&#8221; and nested within it is another bucket called &#8220;Colors&#8221;. In essence, we are presented with more granular information telling the color of each fabric type. Let&#8217;s try another interesting query, one combining nested faceting with independent buckets. Query: &amp;json.facet={Depth:{type:terms,field:Depth_ss,limit:-1},Fabrics:{type:terms,field:Fabric_ss,limit:-1,facet:{Colors:{type:terms,field:Color_ss,limit:-1}}}}&amp;rows=0 Response:\u00a0 Here, as one observes carefully, one bucket stands for independent Depth and other stands for nested facet for Fabric with Color. This enables businesses using Solr to present product information at a granular level for their customers. Some other useful queries include: To view all products and SKU information: Query: q=*:*&amp;rows=10 Response: To fetch specific products and its associated SKUs: Query: q={!child%20of=&#8221;scope_ss:product&#8221;}id:100&amp;wt=json Response: {!child%20of=&#8221;scope_ss:product&#8221;} &#8211; This filter fetches information for all parent products by using the unique field-value pair used to identify a parent doc in index. id:100 &#8211; This filter fetches &#8220;some&#8221; parents based on a specific field-value pair for a parent doc. Updating a nested document in Solr Updating a nested document in Solr involves is a very tricky business. One has to update a complete BLOCK if a single SKU has to be updated or a new SKU has to be added. (THIS IS THE ONLY LIMITATION OF SOLR). This essentially happens because of underlying Lucene handlers. Exact explanation for this, though present, is beyond the scope of this post. Deleting a SKU\/child document The solr document is a little ambiguous about it though based on a simple POC, its clear that one can remove a child doc from solr by using a simple delete by ID API. One can invoke update handler for core\/collection as below: Query: update?stream.body=&lt;delete&gt;&lt;query&gt;id:101&lt;\/query&gt;&lt;\/delete&gt;&amp;commit=true Response:\u00a0 This removes the child document with id:101 from index So, that&#8217;s it for today. Will be back with another interesting post on Solr.<\/p>\n","protected":false},"author":3,"featured_media":839,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[41],"tags":[105,107,91,106],"class_list":["post-814","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-solr","tag-nested-doc-solr","tag-nested-structure-solr","tag-solr-index","tag-solr-nested-documents"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v23.1 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Indexing and Searching Nested Documents in Solr - Ultimate Solr Guide - Aeologic Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Indexing and Searching Nested Documents in Solr - Ultimate Solr Guide - Aeologic Blog\" \/>\n<meta property=\"og:description\" content=\"Hi All, Today I will be writing about another important aspect of Solr that encapsulates the need of a lot of business applications. Suppose we need to index data of an e-commerce company that wants to host a variety of products on their websites along with associated SKU&#8217;s. This data needs to be indexed, updated, searched upon in a way that is legible to both the end-users and the merchandisers. So, a natural question arises, how to represent this data? Also, what matrix to follow in order to maintain the data easily and effectively? To address this problem, Solr provides us with a mechanism to associate multiple docs with each other and put them in a relationship. Also, it provides both indexing and searching mechanisms to get data in and out. What we are referring to here is called a &#8220;Nested document structure&#8221;, or more technically, a BLOCK in Solr. Put simply, a block is a set of parent-child relation between multiple documents. Let&#8217;s understand this in two parts. Indexing Nested Documents Let&#8217;s assume a nested structure as below: { &#8220;id&#8221;:&#8221;100&#8243;, &#8220;scope_ss&#8221;:&#8221;product&#8221;, &#8220;category_ss&#8221;:&#8221;OutdoorSofa&#8221;, &#8220;productType_ss&#8221;:&#8221;sofa&#8221;, &#8220;_childDocuments_&#8220;: [ { &#8220;id&#8221;:&#8221;101&#8243;, &#8220;scope_ss&#8221;:&#8221;sku&#8221;, &#8220;Fabric_ss&#8221;:&#8221;Polyester&#8221;, &#8220;Depth_ss&#8221;:&#8221;Classic&#8221;, &#8220;Finish_ss&#8221; : &#8220;Fine&#8221;, &#8220;Color_ss&#8221;:&#8221;Grey&#8221;}, { &#8220;id&#8221;:&#8221;102&#8243;, &#8220;scope_ss&#8221;:&#8221;sku&#8221;, &#8220;Fabric_ss&#8221;:&#8221;nylon&#8221;, &#8220;Depth_ss&#8221;:&#8221;Petite&#8221;, &#8220;Finish_ss&#8221; : &#8220;Grey&#8221;, &#8220;Color_ss&#8221;:&#8221;Green&#8221;}, { &#8220;id&#8221;:&#8221;103&#8243;, &#8220;scope_ss&#8221;:&#8221;sku&#8221;, &#8220;Fabric_ss&#8221;:&#8221;acrylic&#8221;, &#8220;Depth_ss&#8221;:&#8221;Petite&#8221;, &#8220;Finish_ss&#8221; : &#8220;Espresso&#8221;, &#8220;Color_ss&#8221;:&#8221;Green&#8221;}, { &#8220;id&#8221;:&#8221;104&#8243;, &#8220;scope_ss&#8221;:&#8221;sku&#8221;, &#8220;Fabric_ss&#8221;:&#8221;Polyester&#8221;, &#8220;Depth_ss&#8221;: &#8220;Classic&#8221;, &#8220;Finish_ss&#8221; : &#8220;Grey&#8221;, &#8220;Color_ss&#8221;:&#8221;Dove&#8221;}, {&#8220;id&#8221;:&#8221;105&#8243;, &#8220;scope_ss&#8221;:&#8221;sku&#8221;, &#8220;Fabric_ss&#8221;:&#8221;nylon&#8221;, &#8220;Depth_ss&#8221;: &#8220;Classic&#8221;, &#8220;Finish_ss&#8221; : &#8220;Grey&#8221;, &#8220;Color_ss&#8221;:&#8221;Blue&#8221;}] } _childDocuments_\u00a0tells solr that each object defined within the scope is a child to the doc it belongs to. In essence, we have just created a block of information that has properties for SKU&#8217;s which imparts some meaning to the application scenarios. Now let&#8217;s see how we can index the doc. Utilizing Solr&#8217;s dynamic schema mapping capabilities, we can be certain that all the fields in the document will get indexed and get reflected (Notice _ss in fields, they are stored as String array). Now, one may ask upon careful observation that why the data type used is array when the field is storing String type information. Answer to this question lies in more subtle understanding of inner working of Solr. When Solr indexes a nested document, it stores all field values for a field in a set. This effectively means each field has multiple values and hence the type, array of String. If one tries to index data without using _ss or just _s (String type in Solr), solr engine throws an error. Now, assuming we have settled with basics, let&#8217;s continue to index the data. Fire up UI and index data by navigating to necessary modalities as below: Paste the JSON doc in &#8220;Documents(s)&#8221; section and index the document. If all configuration is proper, then, the index upon querying will appear as below: Note: Notice how the parent doc (the product information) is referenced at bottom and child docs are piled upon it. This is not by accident but by design. Querying Nested Documents Let&#8217;s dive into basics of querying nested docs in Solr. One of the most needed use-case in context of e-commerce data-set is Faceting. Faceting for nested docs by design is different than traditional docs in Solr. To understand this, let&#8217;s generate facets for Color_ss and Fabric_ss fields. Query Syntax: &amp;json.facet={Fabrics:{type:terms,field:Fabric_ss,limit:-1},Colors:{type:terms,field:Color_ss,limit:-1}}&amp;rows=0 Response: If one observes carefully, one can see clearly how two buckets for each of the fields is formed. First bucket for Fabrics and second bucket for colors. Its worth mentioning here that the name, &#8220;Fabrics&#8221; and &#8220;Colors&#8221; are custom headers and can be changed at will. Lets try something else. Let&#8217;s try nested faceting here. Query: &amp;json.facet={Fabrics:{type:terms,field:Fabric_ss,limit:-1,facet:{Colors:{type:terms,field:Color_ss,limit:-1}}}}&amp;rows=0 Response: Here, we have a bucket called &#8220;Fabrics&#8221; and nested within it is another bucket called &#8220;Colors&#8221;. In essence, we are presented with more granular information telling the color of each fabric type. Let&#8217;s try another interesting query, one combining nested faceting with independent buckets. Query: &amp;json.facet={Depth:{type:terms,field:Depth_ss,limit:-1},Fabrics:{type:terms,field:Fabric_ss,limit:-1,facet:{Colors:{type:terms,field:Color_ss,limit:-1}}}}&amp;rows=0 Response:\u00a0 Here, as one observes carefully, one bucket stands for independent Depth and other stands for nested facet for Fabric with Color. This enables businesses using Solr to present product information at a granular level for their customers. Some other useful queries include: To view all products and SKU information: Query: q=*:*&amp;rows=10 Response: To fetch specific products and its associated SKUs: Query: q={!child%20of=&#8221;scope_ss:product&#8221;}id:100&amp;wt=json Response: {!child%20of=&#8221;scope_ss:product&#8221;} &#8211; This filter fetches information for all parent products by using the unique field-value pair used to identify a parent doc in index. id:100 &#8211; This filter fetches &#8220;some&#8221; parents based on a specific field-value pair for a parent doc. Updating a nested document in Solr Updating a nested document in Solr involves is a very tricky business. One has to update a complete BLOCK if a single SKU has to be updated or a new SKU has to be added. (THIS IS THE ONLY LIMITATION OF SOLR). This essentially happens because of underlying Lucene handlers. Exact explanation for this, though present, is beyond the scope of this post. Deleting a SKU\/child document The solr document is a little ambiguous about it though based on a simple POC, its clear that one can remove a child doc from solr by using a simple delete by ID API. One can invoke update handler for core\/collection as below: Query: update?stream.body=&lt;delete&gt;&lt;query&gt;id:101&lt;\/query&gt;&lt;\/delete&gt;&amp;commit=true Response:\u00a0 This removes the child document with id:101 from index So, that&#8217;s it for today. Will be back with another interesting post on Solr.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/\" \/>\n<meta property=\"og:site_name\" content=\"Aeologic Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/AeoLogicTech\/\" \/>\n<meta property=\"article:published_time\" content=\"2020-04-18T05:44:18+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/Indexing-and-Searching-Nested-Documents-in-Solr.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1080\" \/>\n\t<meta property=\"og:image:height\" content=\"622\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Manoj Kumar\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@aeologictech\" \/>\n<meta name=\"twitter:site\" content=\"@aeologictech\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Manoj Kumar\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":[\"Article\",\"BlogPosting\"],\"@id\":\"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/\"},\"author\":{\"name\":\"Manoj Kumar\",\"@id\":\"https:\/\/www.aeologic.com\/blog\/#\/schema\/person\/13549984ba8e5f441cc733ed20d7daa4\"},\"headline\":\"Indexing and Searching Nested Documents in Solr &#8211; Ultimate Solr Guide\",\"datePublished\":\"2020-04-18T05:44:18+00:00\",\"dateModified\":\"2020-04-18T05:44:18+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/\"},\"wordCount\":1059,\"publisher\":{\"@id\":\"https:\/\/www.aeologic.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/Indexing-and-Searching-Nested-Documents-in-Solr.png\",\"keywords\":[\"Nested doc solr\",\"Nested structure solr\",\"solr index\",\"Solr nested documents\"],\"articleSection\":[\"Solr\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/\",\"url\":\"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/\",\"name\":\"Indexing and Searching Nested Documents in Solr - Ultimate Solr Guide - Aeologic Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.aeologic.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/Indexing-and-Searching-Nested-Documents-in-Solr.png\",\"datePublished\":\"2020-04-18T05:44:18+00:00\",\"dateModified\":\"2020-04-18T05:44:18+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/#primaryimage\",\"url\":\"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/Indexing-and-Searching-Nested-Documents-in-Solr.png\",\"contentUrl\":\"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/Indexing-and-Searching-Nested-Documents-in-Solr.png\",\"width\":1080,\"height\":622},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.aeologic.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Indexing and Searching Nested Documents in Solr &#8211; Ultimate Solr Guide\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.aeologic.com\/blog\/#website\",\"url\":\"https:\/\/www.aeologic.com\/blog\/\",\"name\":\"Aeologic Blog\",\"description\":\"Aeologic\",\"publisher\":{\"@id\":\"https:\/\/www.aeologic.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.aeologic.com\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.aeologic.com\/blog\/#organization\",\"name\":\"AeoLogic Technologies\",\"url\":\"https:\/\/www.aeologic.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.aeologic.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2022\/05\/new-logo-aeo.jpg\",\"contentUrl\":\"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2022\/05\/new-logo-aeo.jpg\",\"width\":385,\"height\":162,\"caption\":\"AeoLogic Technologies\"},\"image\":{\"@id\":\"https:\/\/www.aeologic.com\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/AeoLogicTech\/\",\"https:\/\/x.com\/aeologictech\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.aeologic.com\/blog\/#\/schema\/person\/13549984ba8e5f441cc733ed20d7daa4\",\"name\":\"Manoj Kumar\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.aeologic.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/24ce77602da5eb5715d74a95733f6c7548e2af73f5a493f9bc0bf55f611d025e?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/24ce77602da5eb5715d74a95733f6c7548e2af73f5a493f9bc0bf55f611d025e?s=96&d=mm&r=g\",\"caption\":\"Manoj Kumar\"},\"description\":\"Manoj Kumar is a seasoned Digital Marketing Manager and passionate Tech Blogger with deep expertise in SEO, AI trends, and emerging digital technologies. He writes about innovative solutions that drive growth and transformation across industry. Featured on - YOURSTORY | TECHSLING | ELEARNINGINDUSTRY | DATASCIENCECENTRAL | TIMESOFINDIA | MEDIUM | DATAFLOQ\",\"sameAs\":[\"https:\/\/www.aeologic.com\/\",\"https:\/\/www.linkedin.com\/in\/manoj-kumar-rajput\/\"],\"url\":\"https:\/\/www.aeologic.com\/blog\/author\/manoj\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Indexing and Searching Nested Documents in Solr - Ultimate Solr Guide - Aeologic Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/","og_locale":"en_US","og_type":"article","og_title":"Indexing and Searching Nested Documents in Solr - Ultimate Solr Guide - Aeologic Blog","og_description":"Hi All, Today I will be writing about another important aspect of Solr that encapsulates the need of a lot of business applications. Suppose we need to index data of an e-commerce company that wants to host a variety of products on their websites along with associated SKU&#8217;s. This data needs to be indexed, updated, searched upon in a way that is legible to both the end-users and the merchandisers. So, a natural question arises, how to represent this data? Also, what matrix to follow in order to maintain the data easily and effectively? To address this problem, Solr provides us with a mechanism to associate multiple docs with each other and put them in a relationship. Also, it provides both indexing and searching mechanisms to get data in and out. What we are referring to here is called a &#8220;Nested document structure&#8221;, or more technically, a BLOCK in Solr. Put simply, a block is a set of parent-child relation between multiple documents. Let&#8217;s understand this in two parts. Indexing Nested Documents Let&#8217;s assume a nested structure as below: { &#8220;id&#8221;:&#8221;100&#8243;, &#8220;scope_ss&#8221;:&#8221;product&#8221;, &#8220;category_ss&#8221;:&#8221;OutdoorSofa&#8221;, &#8220;productType_ss&#8221;:&#8221;sofa&#8221;, &#8220;_childDocuments_&#8220;: [ { &#8220;id&#8221;:&#8221;101&#8243;, &#8220;scope_ss&#8221;:&#8221;sku&#8221;, &#8220;Fabric_ss&#8221;:&#8221;Polyester&#8221;, &#8220;Depth_ss&#8221;:&#8221;Classic&#8221;, &#8220;Finish_ss&#8221; : &#8220;Fine&#8221;, &#8220;Color_ss&#8221;:&#8221;Grey&#8221;}, { &#8220;id&#8221;:&#8221;102&#8243;, &#8220;scope_ss&#8221;:&#8221;sku&#8221;, &#8220;Fabric_ss&#8221;:&#8221;nylon&#8221;, &#8220;Depth_ss&#8221;:&#8221;Petite&#8221;, &#8220;Finish_ss&#8221; : &#8220;Grey&#8221;, &#8220;Color_ss&#8221;:&#8221;Green&#8221;}, { &#8220;id&#8221;:&#8221;103&#8243;, &#8220;scope_ss&#8221;:&#8221;sku&#8221;, &#8220;Fabric_ss&#8221;:&#8221;acrylic&#8221;, &#8220;Depth_ss&#8221;:&#8221;Petite&#8221;, &#8220;Finish_ss&#8221; : &#8220;Espresso&#8221;, &#8220;Color_ss&#8221;:&#8221;Green&#8221;}, { &#8220;id&#8221;:&#8221;104&#8243;, &#8220;scope_ss&#8221;:&#8221;sku&#8221;, &#8220;Fabric_ss&#8221;:&#8221;Polyester&#8221;, &#8220;Depth_ss&#8221;: &#8220;Classic&#8221;, &#8220;Finish_ss&#8221; : &#8220;Grey&#8221;, &#8220;Color_ss&#8221;:&#8221;Dove&#8221;}, {&#8220;id&#8221;:&#8221;105&#8243;, &#8220;scope_ss&#8221;:&#8221;sku&#8221;, &#8220;Fabric_ss&#8221;:&#8221;nylon&#8221;, &#8220;Depth_ss&#8221;: &#8220;Classic&#8221;, &#8220;Finish_ss&#8221; : &#8220;Grey&#8221;, &#8220;Color_ss&#8221;:&#8221;Blue&#8221;}] } _childDocuments_\u00a0tells solr that each object defined within the scope is a child to the doc it belongs to. In essence, we have just created a block of information that has properties for SKU&#8217;s which imparts some meaning to the application scenarios. Now let&#8217;s see how we can index the doc. Utilizing Solr&#8217;s dynamic schema mapping capabilities, we can be certain that all the fields in the document will get indexed and get reflected (Notice _ss in fields, they are stored as String array). Now, one may ask upon careful observation that why the data type used is array when the field is storing String type information. Answer to this question lies in more subtle understanding of inner working of Solr. When Solr indexes a nested document, it stores all field values for a field in a set. This effectively means each field has multiple values and hence the type, array of String. If one tries to index data without using _ss or just _s (String type in Solr), solr engine throws an error. Now, assuming we have settled with basics, let&#8217;s continue to index the data. Fire up UI and index data by navigating to necessary modalities as below: Paste the JSON doc in &#8220;Documents(s)&#8221; section and index the document. If all configuration is proper, then, the index upon querying will appear as below: Note: Notice how the parent doc (the product information) is referenced at bottom and child docs are piled upon it. This is not by accident but by design. Querying Nested Documents Let&#8217;s dive into basics of querying nested docs in Solr. One of the most needed use-case in context of e-commerce data-set is Faceting. Faceting for nested docs by design is different than traditional docs in Solr. To understand this, let&#8217;s generate facets for Color_ss and Fabric_ss fields. Query Syntax: &amp;json.facet={Fabrics:{type:terms,field:Fabric_ss,limit:-1},Colors:{type:terms,field:Color_ss,limit:-1}}&amp;rows=0 Response: If one observes carefully, one can see clearly how two buckets for each of the fields is formed. First bucket for Fabrics and second bucket for colors. Its worth mentioning here that the name, &#8220;Fabrics&#8221; and &#8220;Colors&#8221; are custom headers and can be changed at will. Lets try something else. Let&#8217;s try nested faceting here. Query: &amp;json.facet={Fabrics:{type:terms,field:Fabric_ss,limit:-1,facet:{Colors:{type:terms,field:Color_ss,limit:-1}}}}&amp;rows=0 Response: Here, we have a bucket called &#8220;Fabrics&#8221; and nested within it is another bucket called &#8220;Colors&#8221;. In essence, we are presented with more granular information telling the color of each fabric type. Let&#8217;s try another interesting query, one combining nested faceting with independent buckets. Query: &amp;json.facet={Depth:{type:terms,field:Depth_ss,limit:-1},Fabrics:{type:terms,field:Fabric_ss,limit:-1,facet:{Colors:{type:terms,field:Color_ss,limit:-1}}}}&amp;rows=0 Response:\u00a0 Here, as one observes carefully, one bucket stands for independent Depth and other stands for nested facet for Fabric with Color. This enables businesses using Solr to present product information at a granular level for their customers. Some other useful queries include: To view all products and SKU information: Query: q=*:*&amp;rows=10 Response: To fetch specific products and its associated SKUs: Query: q={!child%20of=&#8221;scope_ss:product&#8221;}id:100&amp;wt=json Response: {!child%20of=&#8221;scope_ss:product&#8221;} &#8211; This filter fetches information for all parent products by using the unique field-value pair used to identify a parent doc in index. id:100 &#8211; This filter fetches &#8220;some&#8221; parents based on a specific field-value pair for a parent doc. Updating a nested document in Solr Updating a nested document in Solr involves is a very tricky business. One has to update a complete BLOCK if a single SKU has to be updated or a new SKU has to be added. (THIS IS THE ONLY LIMITATION OF SOLR). This essentially happens because of underlying Lucene handlers. Exact explanation for this, though present, is beyond the scope of this post. Deleting a SKU\/child document The solr document is a little ambiguous about it though based on a simple POC, its clear that one can remove a child doc from solr by using a simple delete by ID API. One can invoke update handler for core\/collection as below: Query: update?stream.body=&lt;delete&gt;&lt;query&gt;id:101&lt;\/query&gt;&lt;\/delete&gt;&amp;commit=true Response:\u00a0 This removes the child document with id:101 from index So, that&#8217;s it for today. Will be back with another interesting post on Solr.","og_url":"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/","og_site_name":"Aeologic Blog","article_publisher":"https:\/\/www.facebook.com\/AeoLogicTech\/","article_published_time":"2020-04-18T05:44:18+00:00","og_image":[{"width":1080,"height":622,"url":"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/Indexing-and-Searching-Nested-Documents-in-Solr.png","type":"image\/png"}],"author":"Manoj Kumar","twitter_card":"summary_large_image","twitter_creator":"@aeologictech","twitter_site":"@aeologictech","twitter_misc":{"Written by":"Manoj Kumar","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":["Article","BlogPosting"],"@id":"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/#article","isPartOf":{"@id":"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/"},"author":{"name":"Manoj Kumar","@id":"https:\/\/www.aeologic.com\/blog\/#\/schema\/person\/13549984ba8e5f441cc733ed20d7daa4"},"headline":"Indexing and Searching Nested Documents in Solr &#8211; Ultimate Solr Guide","datePublished":"2020-04-18T05:44:18+00:00","dateModified":"2020-04-18T05:44:18+00:00","mainEntityOfPage":{"@id":"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/"},"wordCount":1059,"publisher":{"@id":"https:\/\/www.aeologic.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/#primaryimage"},"thumbnailUrl":"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/Indexing-and-Searching-Nested-Documents-in-Solr.png","keywords":["Nested doc solr","Nested structure solr","solr index","Solr nested documents"],"articleSection":["Solr"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/","url":"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/","name":"Indexing and Searching Nested Documents in Solr - Ultimate Solr Guide - Aeologic Blog","isPartOf":{"@id":"https:\/\/www.aeologic.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/#primaryimage"},"image":{"@id":"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/#primaryimage"},"thumbnailUrl":"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/Indexing-and-Searching-Nested-Documents-in-Solr.png","datePublished":"2020-04-18T05:44:18+00:00","dateModified":"2020-04-18T05:44:18+00:00","breadcrumb":{"@id":"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/#primaryimage","url":"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/Indexing-and-Searching-Nested-Documents-in-Solr.png","contentUrl":"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2020\/04\/Indexing-and-Searching-Nested-Documents-in-Solr.png","width":1080,"height":622},{"@type":"BreadcrumbList","@id":"https:\/\/www.aeologic.com\/blog\/indexing-and-searching-nested-documents-in-solr-ultimate-solr-guide\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.aeologic.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Indexing and Searching Nested Documents in Solr &#8211; Ultimate Solr Guide"}]},{"@type":"WebSite","@id":"https:\/\/www.aeologic.com\/blog\/#website","url":"https:\/\/www.aeologic.com\/blog\/","name":"Aeologic Blog","description":"Aeologic","publisher":{"@id":"https:\/\/www.aeologic.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.aeologic.com\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.aeologic.com\/blog\/#organization","name":"AeoLogic Technologies","url":"https:\/\/www.aeologic.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.aeologic.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2022\/05\/new-logo-aeo.jpg","contentUrl":"https:\/\/www.aeologic.com\/blog\/wp-content\/uploads\/2022\/05\/new-logo-aeo.jpg","width":385,"height":162,"caption":"AeoLogic Technologies"},"image":{"@id":"https:\/\/www.aeologic.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/AeoLogicTech\/","https:\/\/x.com\/aeologictech"]},{"@type":"Person","@id":"https:\/\/www.aeologic.com\/blog\/#\/schema\/person\/13549984ba8e5f441cc733ed20d7daa4","name":"Manoj Kumar","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.aeologic.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/24ce77602da5eb5715d74a95733f6c7548e2af73f5a493f9bc0bf55f611d025e?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/24ce77602da5eb5715d74a95733f6c7548e2af73f5a493f9bc0bf55f611d025e?s=96&d=mm&r=g","caption":"Manoj Kumar"},"description":"Manoj Kumar is a seasoned Digital Marketing Manager and passionate Tech Blogger with deep expertise in SEO, AI trends, and emerging digital technologies. He writes about innovative solutions that drive growth and transformation across industry. Featured on - YOURSTORY | TECHSLING | ELEARNINGINDUSTRY | DATASCIENCECENTRAL | TIMESOFINDIA | MEDIUM | DATAFLOQ","sameAs":["https:\/\/www.aeologic.com\/","https:\/\/www.linkedin.com\/in\/manoj-kumar-rajput\/"],"url":"https:\/\/www.aeologic.com\/blog\/author\/manoj\/"}]}},"_links":{"self":[{"href":"https:\/\/www.aeologic.com\/blog\/wp-json\/wp\/v2\/posts\/814","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.aeologic.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.aeologic.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.aeologic.com\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.aeologic.com\/blog\/wp-json\/wp\/v2\/comments?post=814"}],"version-history":[{"count":0,"href":"https:\/\/www.aeologic.com\/blog\/wp-json\/wp\/v2\/posts\/814\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.aeologic.com\/blog\/wp-json\/wp\/v2\/media\/839"}],"wp:attachment":[{"href":"https:\/\/www.aeologic.com\/blog\/wp-json\/wp\/v2\/media?parent=814"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.aeologic.com\/blog\/wp-json\/wp\/v2\/categories?post=814"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.aeologic.com\/blog\/wp-json\/wp\/v2\/tags?post=814"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}