Azure Cosmos DB design patterns – Part 1: Attribute array

Jay Gordon

Azure Samples / cosmsos-db-design-patterns

Over the years, customers have asked us for help in designing applications around specific scenarios they were trying to achieve. In some cases, these centered around implementing certain patterns using a JSON-based NoSQL database. Some of these patterns are very common in the NoSQL world, but not well understood by those new to NoSQL databases. Other patterns were very specific to the Cosmos DB service itself in demonstrating how to leverage specific capabilities to solve difficult architectural challenges.

We’ve been capturing these patterns and sharing them with customers individually. We felt now was a good time to publish some of these more broadly to make more discoverable by users. The result is Azure Cosmos DB Design Patterns. A repository on GitHub that includes a wide variety of samples that show how to implement specific patterns that will allow you to solve design-related challenges when using Azure Cosmos DB for your solutions.

To help share these, we’ve created a blog post series on each of them. Each post will focus on a specific design pattern with a corresponding sample application that’s featured in this repository. We hope you enjoy and find this series useful.

Azure Cosmos DB design pattern: Attribute array

This post will focus on the attribute array pattern. The attribute array pattern creates JSON arrays consisting of multiple similar properties or fields grouped together in a child array versus having as individual properties on the parent object.

The main advantage of this pattern is that rather than creating multiple indexes for every property/field, there is only one path to index. In cases where you have to add another property/field later, it can be easily added to the collection. You can add this attribute easily versus the typical data model change and reindex procedure necessary for property-based attributes. This pattern is especially useful in optimizing indexing in scenarios with sparse properties that may not always contain a value or where the property is not defined when null.

Let’s dive into the Attribute Array NoSQL design pattern using Azure Cosmos DB, illustrated through two practical scenarios:

Scenario 1: Managing Product Sizes

Imagine you’re running an e-commerce website and need to track product sizes like Small, Medium, and Large for different inventory items. In a traditional SQL database, you might create separate fields for each size (e.g., SizeSmall, SizeMedium, SizeLarge). However, with Azure Cosmos DB’s Attribute Array pattern, you can create a more optimized and flexible structure.

Instead of fixed fields on the parent, you use an array property called “Sizes” containing objects with size names and counts. This allows you to easily add new sizes without altering your database schema. Here’s a simplified JSON example:

{
  "id": "unique_product_id",
  "name": "Product Name",
  "category": "Product Category",
  "price": 29.99,
  "sizes": [
    { "name": "Small", "count": 50 },
    { "name": "Medium", "count": 75 },
    { "name": "Large", "count": 60 }
  ]
}

With this setup, querying for products with a count greater than 50 for any size becomes straightforward, using a JOIN expression:

SELECT VALUE p FROM products p JOIN s IN p.sizes WHERE s.count > 50

You can also easily write queries that calculate aggregates such as Sum() by one or more or all sizes. or count the number of attributes in the array itself. There are lots of different ways that storing properties that have denote the same or similar attributes becomes much easier to manage when you store these as a child array in a document. As your product range expands, you won’t need to change your database structure, making it adaptable to evolving needs.

Scenario 2: Handling Room Attributes

Suppose you’re managing hotel rooms with varying attributes like prices in different currencies and sizes measured in square meters and square feet. In a traditional SQL database, you might have separate fields for PriceUSD, PriceEUR, SizeSquareMeters, and SizeSquareFeet or possibly even different tables for hotel rooms in Europe versus the US. Using an Attribute Array approach however, you can create a much simpler data model which is easier to maintain and easier to query.

Instead of predefined fields, you use arrays for the different attributes of prices and sizes:

{
  "id": "unique_room_id",
  "prices": [
    { "currency": "USD", "price": 149.99 },
    { "currency": "EUR", "price": 129.99 }
  ],
  "sizes": [
    { "unitMeasurement": "SquareMeters", "size": 30 },
    { "unitMeasurement": "SquareFeet", "size": 323 }
  ]
}

Now, if you want to find rooms with prices exceeding 750 in any currency or sizes greater than 200 in any unit, you can easily construct queries:

SELECT VALUE r FROM rooms r JOIN p IN r.prices WHERE p.price > 750
SELECT VALUE r FROM rooms r JOIN s IN r.sizes WHERE s.size > 200

This approach makes it simpler to adapt to changes in currencies or measurement units without altering your database schema.

In both scenarios, the Attribute Array design pattern in Azure Cosmos DB offers flexibility, scalability, and adaptability, making it a powerful choice for handling dynamic and evolving data structures.

By converting similar properties\fields to collections, you can improve many aspects of your data model and the queries that run against them. You can also in some cases drastically reduce the size of your indexes improving the performance and cost for both queries and writes.

Getting Started with Azure Cosmos DB Design Patterns

You take a look at the sample code by visiting the attribute array pattern on GitHub. You can also try this out for yourself by visiting the Azure Cosmos DB Design Patterns GitHub repo and cloning or forking it. Then run locally or from Code Spaces in GitHub. If you are new to Azure Cosmos DB, we got you covered with a free Azure Cosmos DB account for 30 days, no credit card required. If you want more time, you can extend the free period. You can even upgrade too.

Sign up for your free Azure Cosmos DB account at aka.ms/trycosmosdb.

Explore this and the other design patterns and see how Azure Cosmos DB can enhance your application development and data modeling efforts. Whether you’re an experienced developer or just getting started, the free trial allows you to discover the benefits firsthand.

To get started with Azure Cosmos DB Design Patterns, follow these steps:

  1. Visit the GitHub repository and explore the various design patterns and best practices provided.
  2. Clone or download the repository to access the sample code and documentation.
  3. Review the README files and documentation for each design pattern to understand when and how to apply them to your Azure Cosmos DB projects.
  4. Experiment with the sample code and adapt it to your specific use cases.

About Azure Cosmos DB

Azure Cosmos DB is a fully managed and serverless distributed database for modern app development, with SLA-backed speed and availability, automatic and instant scalability, and support for open-source PostgreSQL, MongoDB, and Apache Cassandra. Try Azure Cosmos DB for free here. To stay in the loop on Azure Cosmos DB updates, follow us on Twitter, YouTube, and LinkedIn.

0 comments

Discussion is closed.

Feedback usabilla icon