Understanding the parentId Property

You can use the parentId property when adding or updating an item in a Push source to establish a parent-child relationship between items (see Defining Parent-Child Relationships). Specifying a parentId when pushing an item always populates the @topparent and @topparentid fields for that item. In addition, if the parentId value differs from the documentId value of the pushed item, the @isattachment and @attachmentparentid fields are populated as well. You can use the @topparent and @isattachment fields to request folded query results from the Search API (see Requesting and Rendering Folded Query Results). For their part, the @topparentid and @attachmentparentid fields are meant to be used in nested queries (see Executing Nested Queries).

Defining Parent-Child Relationships

When specified, the parentId parameter must correlate with the documentId of a parent item.

This means that:

  • A parent item must have its own documentId as its parentId.
  • A child item must have the documentId of its parent item as its parentId.

The parentId parameter can only be used to define basic, non-recursive parent-child relationships between items (i.e., a parent can have children, but those children cannot in turn be parents).

If you need to define more deeply nested parent-child relationships (e.g., between forum discussions, their messages, and the files attached to those message), you must push custom metadata to populate a set of folding fields in your index (see Result Folding).

In a Push source that indexes movie-related items, you want to define parent-child relationships between director items and movie items.

  1. You create a large file container (see Creating a File Container).

    Request

     POST https://push.cloud.coveo.com/v1/organizations/coveomovieorganization/files HTTP/1.1
        
     Content-Type: application/json
     Accept: application/json
     Authorization: Bearer **********-****-****-****-************
    

    Response (201 - Created)

    {
      "uploadUri": "https://s3.amazonaws.com/coveo-nprod-customerdata/proda/blobstore/coveomovieorganizationtp8wu3/2a65f989-2371-4dc6-b6aa-198b5b88ff29?x-amz-security-token=FQoGZXIvYXdzEB8aDL37SykFY6%2FzbYBDPCLlAQmJ0nWbMK0Bxq3wcGnEq1bPcDGsP7dTaKkuuAPOA7LaNZhosW3d8ybg14N8o9OAaUS%2BoQ9Y1oZROmh%2BHZbP7krJAlDRUQS2NtrGxUh20h3GInWxTM5CZ86p5een1Gzsk%2FuCrKCXpqGFJZ1UwEFkEGtj2M2l%2F3eOhfPd6ga9%2F51NgHQPXRc4z%2F5NLiEfWlv%2FxzLZHrtznCjj8fi77QKcLkzO9kiLOtWtZVxmoMg4jVZYwZuOdfRqAVEzaWIsP8lQ2O5AWTwD5O8HKjmtO6v%2FZiV9diYDx7Z7WtrKJg1v2upFHhxljxUo6%2BCG2wU%3D&AWSAccessKeyId=ASIAYKDJLZIT5VRAMAJE&Expires=1533134515&Signature=fyZW7rDLYWSt%2B6rRTPaQPc72uUY%3D",
      "fileId": "b5e8767e-8f0d-4a89-9095-1127915c89c7",
        "requiredHeaders": {
        "x-amz-server-side-encryption": "AES256",
        "Content-Type": "application/octet-stream"
      }
    }
    
  2. You upload a batch into the container, using the parentId property to define parent-child relationships between items as required (see Managing Batches of Items in a Push Source - Step 2).

    Request

     PUT https://s3.amazonaws.com/coveo-nprod-customerdata/proda/blobstore/coveomovieorganizationtp8wu3/2a65f989-2371-4dc6-b6aa-198b5b88ff29?x-amz-security-token=FQoGZXIvYXdzEB8aDL37SykFY6%2FzbYBDPCLlAQmJ0nWbMK0Bxq3wcGnEq1bPcDGsP7dTaKkuuAPOA7LaNZhosW3d8ybg14N8o9OAaUS%2BoQ9Y1oZROmh%2BHZbP7krJAlDRUQS2NtrGxUh20h3GInWxTM5CZ86p5een1Gzsk%2FuCrKCXpqGFJZ1UwEFkEGtj2M2l%2F3eOhfPd6ga9%2F51NgHQPXRc4z%2F5NLiEfWlv%2FxzLZHrtznCjj8fi77QKcLkzO9kiLOtWtZVxmoMg4jVZYwZuOdfRqAVEzaWIsP8lQ2O5AWTwD5O8HKjmtO6v%2FZiV9diYDx7Z7WtrKJg1v2upFHhxljxUo6%2BCG2wU%3D&AWSAccessKeyId=ASIAYKDJLZIT5VRAMAJE&Expires=1533134515&Signature=fyZW7rDLYWSt%2B6rRTPaQPc72uUY%3D HTTP/1.1
     
     Content-Type: application/octet-stream
     x-amz-server-side-encryption: "AES256"
    

    Payload

     {
       "addOrUpdate": [
         {
           "title": "Edgar Wright",
           "data": "...",
           "documentId": "file://directors/edgar-wright.txt",
           "parentId": "file://directors/edgar-wright.txt",
           "documenttype": "Director"
         },
         {
           "title": "The World's End",
           "data": "...",
           "documentId": "file://movies/the-world-s-end.txt",
           "parentId": "file://directors/edgar-wright.txt",
           "documenttype": "Movie"
         },
         {
           "title": "Baby Driver",
           "data": "...",
           "documentId": "file://movies/baby-driver.txt",
           "parentId": "file://directors/edgar-wright.txt",
           "documenttype": "Movie"
         },
         {
           "title": "Stanley Kubrick",
           "data": "...",
           "documentId": "file://directors/stanley-kubrick.txt",
           "parentId": "file://directors/stanley-kubrick.txt",
           "documenttype": "Director"
         },
         {
           "title": "The Shining",
           "data": "...",
           "documentId": "file://movies/the-shining.txt",
           "parentId": "file://directors/stanley-kubrick.txt",
           "documenttype": "Movie"
         }
       ],
       "delete": []
     }
    
  3. You push the large file container into your source (see Managing Batches of Items in a Push Source - Step 3).

    Request

     POST https://push.cloud.coveo.com/v1/organizations/coveomovieorganization/sources/vzievcixq66qq5q6xulpy32dqi-coveomovieorganization/documents/batch?fileId=b5e8767e-8f0d-4a89-9095-1127915c89c7 HTTP/1.1
        
     Content-Type: application/json
     Authorization: Bearer **********-****-****-****-************
    

    Response (202 - Accepted)

    null
    

Requesting and Rendering Folded Query Results

Once you have defined parent-child relationships between items, you can use the @topparent and @isattachment fields to request folded query results from the Search API.

In a search interface that relies on the Coveo JavaScript Search Framework, you can achieve this by configuring a FoldingForThread component as follows:

  • Set the field and child options to @topparent.
  • Set the parent option to @isattachment.

You can then use the ResultFolding result template component to render returned folded query results properly.

In a Coveo JavaScript Search Framework search page, you want to request and render folded query results from a Push source named MoviePush. In that source, any item whose @documenttype is Director may have child results (see the example in Defining Parent-Child Relationships).

  1. You include an adequately configured FoldingForThread component in your search page.

    <body id="search" class="CoveoSearchInterface">
      <!-- ... -->
      <div class="CoveoFoldingForThread" data-field="@topparent" data-parent="@isattachment" data-child="@topparent">
      <!-- ... -->
    </body>
    
  2. You add a ResultFolding component in the result template which applies to Director query result items from the MoviePush source.

    <!-- ... -->
    <div class="CoveoResultList">
      <!-- ... -->
      <script id="MovieDirectorTemplate" type="text/html" class="result-template" data-field-source="MoviePush" data-field-documenttype="Director">
        <div class="coveo-result-frame">
          <div class="coveo-result-row">
            <div class="coveo-result-cell">
              <span class="CoveoIcon"></span>
              <a class="CoveoResultLink"></a>
            </div>
          </div>
          <div class="coveo-result-row">
            <div class="coveo-result-cell">
              <span class="CoveoResultFolding"></span>
            </div>
        </div>
      </script>
      <!-- ... -->
    </div>
    <!-- ... -->
    
  3. You load the search page in a browser and submit a query that returns folded query results from the MoviePush source. The rendered result list looks similar to this:

    Folded Results Search Interface

If you need to request folded query results based on the @topparent and @isattachment field by invoking the Search API directly:

  • Set the filterField and parentField search request parameters to @topparent.
  • Set the childField search request parameter to @isattachment.

Request

POST https://platform.cloud.coveo.com/rest/search/v2?organizationId=coveomovieorganization HTTP/1.1
 
Content-Type: application/json
Accept: application/json
Authorization: Bearer **********-****-****-****-************

Payload

{
    ...
    "cq": "@source==MoviePush",
    "filterField": "@topparent",
    "parentField": "@topparent",
    "childField": "@isattachment"
    ...
}

Response (200 - OK)

{
  "totalCount": 2,
  ...
  "results": [
    {
      "title": "The Shining",
      "uri": "file://movies/the-shining.txt",
      ...
      "parentResult": {
        "title": "Stanley Kubrick",
        "uri": "file://directors/stanley-kubrick.txt",
        "parentResult": null,
        ...
      },
      "childResults": [
        {
          "title": "Stanley Kubrick",
          "uri": "file://directors/stanley-kubrick.txt",
          "parentResult": null,
          ...
        }
      ],
      ...
    },
    {
      "title": "Baby Driver",
      "uri": "file://movies/baby-driver.txt",
      ...
      "parentResult": {
        "title": "Edgar Wright",
        "uri": "file://directors/edgar-wright.txt",
        "parentResult": null,
        ...
      },
      "childResults": [
        {
          "title": "The World's End",
          "uri": "file://movies/the-world-s-end.txt",
          "parentResult": {
            "title": "Edgar Wright",
            "uri": "file://directors/edgar-wright.txt",
            ...
          }
          ...
        },
        {
          "title": "Edgar Wright",
          "uri": "file://directors/edgar-wright.txt",
          "parentResult": null,
          ...
        }
      ],
      ...
    }
  ]
}

Executing Nested Queries

The @topparentid and @attachmentparentid numeric fields, which get populated for an item in a Push source when a parent-child relationship is defined through the parentId parameter for that item, can be useful in nested queries, as they can be processed roughly ten times faster than the corresponding string fields (i.e., @topparent and @isattachment).

Ensure that the Use Cache For Numeric Queries field parameter is enabled for the nested query field, in this case attachmentparentid (see Add or Edit Fields). Doing so will allow for quicker numeric operations (e.g., comparing integers), making query executions faster.

The following query expression returns all items from the MoviePush source that are children of the item whose @topparentid is 32338.

Request

POST https://platform.cloud.coveo.com/rest/search/v2?organizationId=coveomovieorganization HTTP/1.1
 
Content-Type: application/json
Accept: application/json
Authorization: Bearer **********-****-****-****-************

Payload

{
  "q": "@source=MoviePush [[@attachmentparentid] @topparentid=32345]"
}

Response (200 - OK)

{
  "totalCount": 2,
  ...
  "results": [
    {
      "title": "Baby Driver",
      "uri": "file://movies/baby-driver.txt",
      ...
      "raw": {
        ...
        "attachmentparentid": 32345,
        ...
      }
      ...
    },
    {
      "title": "The World's End",
      "uri": "file://movies/the-world-s-end.txt",
      ...
      "raw": {
        ...
        "attachmentparentid": 32345,
        ...
      }
      ...
    }
  ]
}