Take the community feedback survey now.

Sujit Senapati
Oct 31, 2024
  827
(0 votes)

Efficient Catalog Metadata Management and Product Updates Using DTOs in Optimizely Commerce

This post explores ways to manage and update catalog metadata in Optimizely Commerce by utilizing Data Transfer Objects (DTOs). DTOs provide a lightweight, performance-optimized way to access data directly from the database, making them faster and less resource-intensive than using the Content Repository.

Optimizely Commerce’s Content Repository, while feature-rich, can be processing-intensive and costly in terms of performance, especially for large catalogs. By opting for DTOs, this approach minimizes processing load and accelerates data access, making it ideal for scenarios where we need to quickly retrieve and update catalog entries, categories, or metadata.

Setting Up the Metadata Context

First, the metadata context is configured to handle specific culture and language settings. This ensures that all catalog data is accessed in the correct locale, which is critical for applications requiring consistent language or format settings:

string originalMetaDataContextLanguage = CatalogContext.MetaDataContext.Language;
bool originalUseCurrentUiCulture = CatalogContext.MetaDataContext.UseCurrentThreadCulture;

CatalogContext.MetaDataContext.UseCurrentThreadCulture = false;
CatalogContext.MetaDataContext.Language = culture.Name;

Setting UseCurrentThreadCulture to false and explicitly specifying a language allows us to bypass the default culture settings and enforce a consistent data retrieval format.

Retrieving Categories and Entries with DTOs

Using DTOs (specifically CatalogNodeDto and CatalogEntryDto) offers a direct, efficient way to retrieve categories and entries without the performance overhead associated with the Content Repository. By directly accessing catalog nodes and entries, this approach reduces the time taken to retrieve and process the data.

// Retrieve all categories
CatalogNodeDto childNodes = CatalogContext.Current.GetCatalogNodesDto(
    catalogId, 
    new CatalogNodeResponseGroup(CatalogNodeResponseGroup.ResponseGroup.CatalogNodeInfo)
);

// Retrieve entries associated with the catalog node
CatalogEntryDto catalogEntries = CatalogContext.Current.GetCatalogEntriesDto(
    catalogId, 
    new CatalogEntryResponseGroup(CatalogEntryResponseGroup.ResponseGroup.CatalogEntryFull)
);

The GetCatalogNodesDto and GetCatalogEntriesDto methods directly query the database, returning data in a minimal format, which is much faster than loading entire content items with their associated metadata from the Content Repository.

Processing Entries and Updating Variant Associations

With the catalog data retrieved, the code iterates through each catalog entry, filtering based on specific conditions. If an entry meets the criteria, it loads a MetaObject associated with that entry. The MetaObject is then passed to the UpdateProductBasedOnVariantAssociation method, which contains custom logic to update products based on variant relationships:

foreach (var entry in catalogEntries.CatalogEntry)
{
    MetaClass entryMetaClass = MetaClass.Load(CatalogContext.MetaDataContext, entry.MetaClassId);

    if (!entryMetaClass.IsCatalogMetaClass)
        continue;

    if (!entryMetaClass.Name.Contains("Product"))
        continue;

    MetaObject metaObject = MetaObject.Load(CatalogContext.MetaDataContext, entry.CatalogEntryId, entryMetaClass);

    // Custom update logic for products based on variant association
    this.UpdateProductBasedOnVariantAssociation(metaObject, entryMetaClass.Name, entry.Code); 
}

By updating based on variant associations, this approach helps maintain consistency across product variations without requiring heavy content loading operations. Each MetaObject represents the underlying metadata for an entry, allowing for granular updates while keeping performance in check.

Efficient Category Traversal Using In-Order Traversal

The code then proceeds to an in-order traversal of categories (nodes) within childNodes. For each node, we load associated entries and apply the same update logic. Changes need to be accepted after updating the meta object on each level.

foreach (var node in childNodes.CatalogNode)
{
    MetaClass nodeMetaClass = MetaClass.Load(CatalogContext.MetaDataContext, node.MetaClassId);

    if (!nodeMetaClass.IsCatalogMetaClass)
        continue;

    CatalogEntryDto categoryEntries = CatalogContext.Current.GetCatalogEntriesDto(
        catalogId, 
        node.CatalogNodeId, 
        new CatalogEntryResponseGroup(CatalogEntryResponseGroup.ResponseGroup.CatalogEntryFull)
    );

    if (categoryEntries.CatalogEntry.Count == 0)
        continue;

    MetaObject nodeObject = MetaObject.Load(CatalogContext.MetaDataContext, node.CatalogNodeId, nodeMetaClass);

    foreach (var entry in categoryEntries.CatalogEntry)
    {
        MetaClass entryMetaClass = MetaClass.Load(CatalogContext.MetaDataContext, entry.MetaClassId);

        if (!entryMetaClass.IsCatalogMetaClass || !entryMetaClass.Name.Contains("Product"))
            continue;

        MetaObject metaObject = MetaObject.Load(CatalogContext.MetaDataContext, entry.CatalogEntryId, entryMetaClass);

        // Update product based on variant association
        this.UpdateProductBasedOnVariantAssociation(metaObject, entryMetaClass.Name, entry.Code); 

        // Accept changes at the node level to maintain consistency
        nodeObject.AcceptChanges(CatalogContext.MetaDataContext);
    }
}

By using DTOs here, we avoid the overhead of the Content Repository and gain faster access to the underlying data. Each node's metadata is modified only if there are changes, and changes are accepted efficiently, reducing the need for re-indexing or reloading the full catalog.

Restoring Original Metadata Context

Once all updates are complete, we reset the metadata context to its original settings:

CatalogContext.MetaDataContext.Language = originalMetaDataContextLanguage;
CatalogContext.MetaDataContext.UseCurrentThreadCulture = originalUseCurrentUiCulture;

Summary

This approach to catalog metadata management and product updates is both efficient and scalable:

  1. Efficient Data Access with DTOs: DTOs offer a leaner, faster way to access and modify catalog data compared to the Content Repository, ideal for performance-critical scenarios.
  2. Localized Context Settings: Setting a specific culture and language allows for consistent data handling across different locales.
  3. Direct Metadata Modification: Working with MetaObject and MetaClass enables specific, metadata-based updates without the processing load of the full content structure.
  4. Category Traversal and Update: Using in-order traversal allows for efficient updates at the node level, minimizing the need for large-scale re-indexing.

By using DTOs in place of the Content Repository, this method achieves better performance, reducing the overall load on the platform while maintaining an up-to-date, accurate catalog. This technique is especially beneficial for large e-commerce sites where speed and efficiency are critical.

Oct 31, 2024

Comments

Please login to comment.
Latest blogs
A day in the life of an Optimizely OMVP - Creating a blazor add-on for CMS 12

Hello and welcome to another instalment of a day in the life of an Optimizely OMVP. In this post I will be covering how to create a blazor based...

Graham Carr | Oct 14, 2025

AI Tools, MCP, and Function Calling for Optimizely

You can now integrate AI Tools, Model Context Protocol (MCP), and function calling with Optimizely CMS, allowing editors to engage with actual,...

Luc Gosso (MVP) | Oct 14, 2025 |

Optimizely Forms : Setup, Configuration and Submission

I have exploring Optimizely Forms recently –  Installed NuGet package to enable Optimizely Forms, created a Contact Us Form and placed in a landing...

Madhu | Oct 13, 2025 |

Building a Discovery-First MCP for Optimizely CMS – Part 1 of 4

This post kicks off a four-part series on how we’re evolving the Optimizely Model Context Protocol (MCP). The project is still in beta and open...

Johnny Mullaney | Oct 13, 2025 |

Jhoose Security Modules v2.5.0 – Import/Export Configs, .NET 9 Support and More

Discover what’s new in Jhoose Security Modules v2.5.0 — including import/export for configurations, Content Security Policy settings, and security...

Andrew Markham | Oct 9, 2025 |

Quiet Performance Wins: Scheduled Job for SQL Index Maintenance in Optimizely

As Optimizely CMS projects grow, it’s not uncommon to introduce custom tables—whether for integrations, caching, or specialized business logic. But...

Stanisław Szołkowski | Oct 8, 2025 |