solr nested docs: Unable to index docs with children

I am trying to index below nested JSON docs using solrj client.

[
  {
    "id_id_s": "P22!prod",
    "name_lowercase_s": "Mont Blanc Fountain Pen",
    "description_text_en_s": "A Premium Writing Instrument ...",
    "skus": [
      {
        "id_id_s": "P22!S22",
        "color_lowercase_s": "RED",
        "price_int_s": 89,
        "manuals": [
          {
            "id_id_s": "P22!D42",
            "name_text_en_s": "Red Mont Blanc Brochure",
            "pages_int_s": 1,
            "content_text_en_s": "..."
          }
        ]
      },
      {
        "id_id_s": "P22!S32",
        "color_lowercase_s": "BLACK",
        "price_int_s": 67
      }
    ],
    "manuals": [
      {
        "id_id_s": "P22!D52",
        "name_text_en_s": "How To Use A Pen",
        "pages_int_s": 42,
        "content_text_en_s": "Start by removing the cap ..."
      }
    ]
  },
  {
    "id_id_s": "P11!prod",
    "name_lowercase_s": "Swingline Stapler",
    "description_text_en_s": "The Cadillac of office staplers ...",
    "skus": [
      {
        "id_id_s": "P11!S21",
        "color_lowercase_s": "RED",
        "price_int_s": 42,
        "manuals": [
          {
            "id_id_s": "P11!D41",
            "name_lowercase_s": "Red Swingline Brochure",
            "pages_int_s": 1,
            "content_text_en_s": "..."
          }
        ]
      },
      {
        "id_id_s": "P11!S31",
        "color_lowercase_s": "BLACK",
        "price_int_s": 3
      }
    ],
    "manuals": [
      {
        "id_id_s": "P11!D51",
        "name_lowercase_s": "Quick Reference Guide",
        "pages_int_s": 1,
        "content_text_en_s": "How to use your stapler ..."
      },
      {
        "id_id_s": "P11!D61",
        "name_lowercase_s": "Warranty Details",
        "pages_int_s": 42,
        "content_text_en_s": "... lifetime guarantee ..."
      }
    ]
  },
  {
    "id_id_s": "P33!prod",
    "name_text_en_s": "Writo meter gel pen",
    "description_text_en_s": "A Premium Writing Instrument ...",
    "skus": [
      {
        "id_id_s": "P33!S23",
        "color_lowercase_s": "RED",
        "price_int_s": 89,
        "manuals": [
          {
            "id_id_s": "P33!D43",
            "name_text_en_s": "Red color write meter gel pen",
            "pages_int_s": 1,
            "content_text_en_s": "..."
          }
        ]
      },
      {
        "id_id_s": "P33!S33",
        "color_lowercase_s": "BLACK",
        "price_int_s": 67
      }
    ],
    "manuals": [
      {
        "id_id_s": "P33!D53",
        "name_text_en_s": "How To Use A Pen",
        "pages_int_s": 42,
        "content_text_en_s": "Start by removing the cap ..."
      }
    ]
  },
  {
    "id_id_s": "P44!prod",
    "name_text_en_s": "Writo meter gel pen",
    "description_text_en_s": "A Premium Writing Instrument ...",
    "skus_lowercase_m": [
      {
        "id_id_s": "P44!S24",
        "color_lowercase_s": "RED",
        "price_int_s": 89,
        "manuals": [
          {
            "id_id_s": "P44!D44",
            "name_text_en_s": "Red color write meter gel pen",
            "pages_int_s": 1,
            "content_text_en_s": "..."
          }
        ]
      },
      {
        "id_id_s": "P44!S34",
        "color_lowercase_s": "BLACK",
        "price_int_s": 67
      }
    ],
    "manuals_lowercase_m": [
      {
        "id_id_s": "P44!D54",
        "name_text_en_s": "How To Use A Pen",
        "pages_int_s": 42,
        "content_text_en_s": "Start by removing the cap ..."
      }
    ]
  }
]

But while indexing, solr is giving me the below error :
Unable to index docs with children: the schema must include definitions for both a uniqueKey field and the ‘root‘ field, using the exact same fieldTypentat org.apache.solr.client.solrj.impl.HttpSolrClient.executeMethod(HttpSolrClient.java:681)ntat org.apache.solr.client.solrj.impl.HttpSolrClient.request(Http.Solrjava:Client) 266)ntat org.apache.solr.client.solrj.impl.HttpSolrClient.request(HttpSolrClient.java:248)ntat org.apache.solr.client.solrj.impl.LBSolrClient.doRequest(LBSolrClient. java:369)ntat org.apache.solr.client.solrj.impl.LBSolrClient.request(LBSolrClient.java:297)

Any suggestions to resolve the issue will be appreciated.

Attaching the schema file.

  <!-- Update Processors

       Chains of Update Processor Factories for dealing with Update
       Requests can be declared, and then used by name in Update
       Request Processors

       http://wiki.apache.org/solr/UpdateRequestProcessor

    -->
  <field name="_root_" type="string" indexed="true" stored="false" docValues="false" />
  <fieldType name="_nest_path_" class="solr.NestPathField" /> <field name="_nest_path_" type="nest_path" />
  <field name="_nest_parent_" type="string" indexed="true" stored="true" />
  

  <!-- Add unknown fields to the schema

       Field type guessing update processors that will
       attempt to parse string-typed field values as Booleans, Longs,
       Doubles, or Dates, and then add schema fields with the guessed
       field types. Text content will be indexed as "text_general" as
       well as a copy to a plain string version in *_str.

       These require that the schema is both managed and mutable, by
       declaring schemaFactory as ManagedIndexSchemaFactory, with
       mutable specified as true.

       See http://wiki.apache.org/solr/GuessingFieldTypes
    -->
    <updateProcessor class="solr.UUIDUpdateProcessorFactory" name="uuid"/>
  <updateProcessor class="solr.RemoveBlankFieldUpdateProcessorFactory" name="remove-blank"/>
  <updateProcessor class="solr.FieldNameMutatingUpdateProcessorFactory" name="field-name-mutating">
    <str name="pattern">[^w-.]</str>
    <str name="replacement">_</str>
  </updateProcessor>
  <updateProcessor class="solr.ParseBooleanFieldUpdateProcessorFactory" name="parse-boolean"/>
  <updateProcessor class="solr.ParseLongFieldUpdateProcessorFactory" name="parse-long"/>
  <updateProcessor class="solr.ParseDoubleFieldUpdateProcessorFactory" name="parse-double"/>
  <updateProcessor class="solr.ParseDateFieldUpdateProcessorFactory" name="parse-date">
    <arr name="format">
     <str>yyyy-MM-dd'T'HH:mm:ss.SSSZ</str>
        <str>yyyy-MM-dd'T'HH:mm:ss,SSSZ</str>
        <str>yyyy-MM-dd'T'HH:mm:ss.SSS</str>
        <str>yyyy-MM-dd'T'HH:mm:ss,SSS</str>
        <str>yyyy-MM-dd'T'HH:mm:ssZ</str>
        <str>yyyy-MM-dd'T'HH:mm:ss</str>
        <str>yyyy-MM-dd'T'HH:mmZ</str>
        <str>yyyy-MM-dd'T'HH:mm</str>
        <str>yyyy-MM-dd HH:mm:ss.SSSZ</str>
        <str>yyyy-MM-dd HH:mm:ss,SSSZ</str>
        <str>yyyy-MM-dd HH:mm:ss.SSS</str>
        <str>yyyy-MM-dd HH:mm:ss,SSS</str>
        <str>yyyy-MM-dd HH:mm:ssZ</str>
        <str>yyyy-MM-dd HH:mm:ss</str>
        <str>yyyy-MM-dd HH:mmZ</str>
        <str>yyyy-MM-dd HH:mm</str>
        <str>yyyy-MM-dd</str>
    </arr>
  </updateProcessor>
  <updateProcessor class="solr.AddSchemaFieldsUpdateProcessorFactory" name="add-schema-fields">
    <lst name="typeMapping">
      <str name="valueClass">java.lang.String</str>
      <str name="fieldType">text_general</str>
      <lst name="copyField">
        <str name="dest">*_str</str>
        <int name="maxChars">256</int>
      </lst>
      <!-- Use as default mapping instead of defaultFieldType -->
      <bool name="default">true</bool>
    </lst>
    <lst name="typeMapping">
      <str name="valueClass">java.lang.Boolean</str>
      <str name="fieldType">booleans</str>
    </lst>
    <lst name="typeMapping">
      <str name="valueClass">java.util.Date</str>
      <str name="fieldType">pdates</str>
    </lst>
    <lst name="typeMapping">
      <str name="valueClass">java.lang.Long</str>
      <str name="valueClass">java.lang.Integer</str>
      <str name="fieldType">plongs</str>
    </lst>
    <lst name="typeMapping">
      <str name="valueClass">java.lang.Number</str>
      <str name="fieldType">pdoubles</str>
    </lst>
  </updateProcessor>

  <!-- The update.autoCreateFields property can be turned to false to disable schemaless mode -->
  <updateRequestProcessorChain name="add-unknown-fields-to-the-schema" default="${update.autoCreateFields:true}"
           processor="uuid,remove-blank,field-name-mutating,parse-boolean,parse-long,parse-double,parse-date,add-schema-fields">
    <processor class="solr.LogUpdateProcessorFactory"/>
    <processor class="solr.DistributedUpdateProcessorFactory"/>
    <processor class="solr.RunUpdateProcessorFactory"/>
  </updateRequestProcessorChain>

  <!-- Deduplication

       An example dedup update processor that creates the "id" field
       on the fly based on the hash code of some other fields.  This
       example has overwriteDupes set to false since we are using the
       id field as the signatureField and Solr will maintain
       uniqueness based on that anyway.

    -->
  <!--
     <updateRequestProcessorChain name="dedupe">
       <processor class="solr.processor.SignatureUpdateProcessorFactory">
         <bool name="enabled">true</bool>
         <str name="signatureField">id</str>
         <bool name="overwriteDupes">false</bool>
         <str name="fields">name,features,cat</str>
         <str name="signatureClass">solr.processor.Lookup3Signature</str>
       </processor>
       <processor class="solr.LogUpdateProcessorFactory" />
       <processor class="solr.RunUpdateProcessorFactory" />
     </updateRequestProcessorChain>
    -->

  <!-- Response Writers

       http://wiki.apache.org/solr/QueryResponseWriter

       Request responses will be written using the writer specified by
       the 'wt' request parameter matching the name of a registered
       writer.

       The "default" writer is the default and will be used if 'wt' is
       not specified in the request.
    -->
  <!-- The following response writers are implicitly configured unless
       overridden...
    -->
  <!--
     <queryResponseWriter name="xml"
                          default="true"
                          class="solr.XMLResponseWriter" />
     <queryResponseWriter name="json" class="solr.JSONResponseWriter"/>
     <queryResponseWriter name="python" class="solr.PythonResponseWriter"/>
     <queryResponseWriter name="ruby" class="solr.RubyResponseWriter"/>
     <queryResponseWriter name="php" class="solr.PHPResponseWriter"/>
     <queryResponseWriter name="phps" class="solr.PHPSerializedResponseWriter"/>
     <queryResponseWriter name="csv" class="solr.CSVResponseWriter"/>
     <queryResponseWriter name="schema.xml" class="solr.SchemaXmlResponseWriter"/>
    -->

  <queryResponseWriter name="json" class="solr.JSONResponseWriter">
    <!-- For the purposes of the tutorial, JSON responses are written as
     plain text so that they are easy to read in *any* browser.
     If you expect a MIME type of "application/json" just remove this override.
    -->
    <str name="content-type">text/plain; charset=UTF-8</str>
  </queryResponseWriter>

  <!-- Query Parsers

       https://lucene.apache.org/solr/guide/query-syntax-and-parsing.html

       Multiple QParserPlugins can be registered by name, and then
       used in either the "defType" param for the QueryComponent (used
       by SearchHandler) or in LocalParams
    -->
  <!-- example of registering a query parser -->
  <!--
     <queryParser name="myparser" class="com.mycompany.MyQParserPlugin"/>
    -->

  <!-- Function Parsers

       http://wiki.apache.org/solr/FunctionQuery

       Multiple ValueSourceParsers can be registered by name, and then
       used as function names when using the "func" QParser.
    -->
  <!-- example of registering a custom function parser  -->
  <!--
     <valueSourceParser name="myfunc"
                        class="com.mycompany.MyValueSourceParser" />
    -->


  <!-- Document Transformers
       http://wiki.apache.org/solr/DocTransformers
    -->
  <!--
     Could be something like:
     <transformer name="db" class="com.mycompany.LoadFromDatabaseTransformer" >
       <int name="connection">jdbc://....</int>
     </transformer>

     To add a constant value to all docs, use:
     <transformer name="mytrans2" class="org.apache.solr.response.transform.ValueAugmenterFactory" >
       <int name="value">5</int>
     </transformer>

     If you want the user to still be able to change it with _value:something_ use this:
     <transformer name="mytrans3" class="org.apache.solr.response.transform.ValueAugmenterFactory" >
       <double name="defaultValue">5</double>
     </transformer>

      If you are using the QueryElevationComponent, you may wish to mark documents that get boosted.  The
      EditorialMarkerFactory will do exactly that:
     <transformer name="qecBooster" class="org.apache.solr.response.transform.EditorialMarkerFactory" />
    -->
</config>

I am following the below solr doc to index the nested documents. https://solr.apache.org/guide/8_11/indexing-nested-documents.html

java code : solrClient = createCloudSolrClient(true, app); solrClient.setDefaultCollection(collectionName); ContentStreamUpdateRequest solrRequest = new ContentStreamUpdateRequest("/update"); solrRequest.addContentStream(new ContentStreamBase.StringStream(jsonQueryString.toString(), "application/json"))); solrRequest.setAction(AbstractUpdateRequest.ACTION.COMMIT, true, true); solrClient.request(solrRequest);

Leave a Comment