Data Document Recursion

I currently have a data document that looks like this (oversimplified):

    <dataDocuments dataDocumentId="PopcStore" indexName="popc" documentName="Store"
                   primaryEntityName="mantle.product.store.ProductStore" documentTitle="StoreNameTemplate">
        <fields fieldSeqId="01" fieldPath="productStoreId"/>

        <fields fieldSeqId="10" fieldPath="categories:category:productCategoryId"/>

        <fields fieldSeqId="40" fieldPath="categories:category:children:category:productCategoryId" fieldNameAlias="childProductCategoryId"/>

        <fields fieldSeqId="50" fieldPath="categories:category:children:category:children:category:productCategoryId" fieldNameAlias="childChildProductCategoryId"/>

    </dataDocuments>

This is to list out all of the ProductCategories in relation to a ProductStore. However, the problem is that every category can have sub categories that have sub categories meaning that recursion comes into play.

What I would like to do is have a Data Document that would display a ProductCategory's children indefinitely. For example a DataDocument that would look like this:

    <dataDocuments dataDocumentId="PopcStore" indexName="popc" documentName="Store"
                   primaryEntityName="mantle.product.store.ProductStore" documentTitle="StoreNameTemplate">
        <fields fieldSeqId="01" fieldPath="productStoreId"/>

        <fields fieldSeqId="10" fieldPath="categories:category:productCategoryId"/>

        <RecursiveField fieldSeqId="40" firstFieldPath="categories:category" fieldChangePath="children:category"
 fieldNameAlias="childProductCategoryId"/>

    </dataDocuments>

Or something like that.

Another possibility that wouldn’t require an additional entity would be something like this:

    <dataDocuments dataDocumentId="PopcStore" indexName="popc" documentName="Store"
                   primaryEntityName="mantle.product.store.ProductStore" documentTitle="StoreNameTemplate">
        <fields fieldSeqId="01" fieldPath="productStoreId"/>

        <fields fieldSeqId="10" fieldPath="categories:category:productCategoryId"/>

        <fields fieldSeqId="40" fieldPath="PopcStore:categories:category:children:category:productCategoryId" fieldNameAlias="childProductCategoryId"/>

    </dataDocuments>

Maybe it’s possible, if not I have another solution. I’m mostly just curious.

For what I think you’re describing you’d want ProductCategory to be the primary entity and go the other way to get to the store. The reason for that is to search for a ProductCategory you would want one document in Open/ElasticSearch for each ProductCategory, rather than a single document per product that would have a full tree of categories related to the ProductStore (which for some stores could be a bit large, especially to manually search through in memory on the app server).

With one DataDocument instance per ProductCategory, the main thing you need is a productStoreId field (or list of productStoreId fields that the category is related to through one or more categories).

As you mentioned there is a problem with this sort of thing when arbitrary tree depth (or actually graph width, ProductCategoryRollup has the parent/child notion but because it is a many-to-many relationship via this join entity a child can have an arbitrary number of parents, there can be loops, etc).

The main way I can think of for to handle this would be to write a service that does multiple queries and iteratively or recursively looks for category paths to product stores to get a List/Array of productStoreId. This service would be configured on the data document to augment the document data. The main OOTB example of this is in the MantleWikiPage DataDocument with:

manualDataServiceName="org.moqui.impl.WikiServices.get#WikiPageManualDocumentData"

1 Like

I ended up realizing this thanks.

I’ve got that figured out.

Hmmm

Alright. I’ll check that out.

Thanks. I got that working

Tangential to the topic but is this better suited for a database query rather than data docs? It would not change the fact that you need to handle multiple parent / child relationships so maybe it doesn’t matter, a database query would just be changing the source of the data. You just have to know how to retrieve and manipulate data from data docs.

1 Like