Cosmos modeling question (nested queries)

Vinicius Carvalho 1 Reputation point
2022-11-01T20:51:42.757+00:00

Hi there, I'm starting with cosmos, and I have a simple document that contains a lot of nested data. This document is mostly static, as few updates should happen to it. It maps a Magazine with its internal pages.

On a relational db I would have set a Magazine Table and a FK to a Pages table, but in cosmos I decided to embedded it.

{  
"id" : "randomUUID",  
    "release" : "1989-7-1",  
    "pages" : [  
      {  
        "number" : 0,  
        "position" : 0,  
        "type" : "cover",  
        "tags" : ["Disney"]  
      },  
      {  
        "number" : 3,  
        "position" : 4,  
        "type" : "ads",  
        "tags" : ["Nintendo"],  
        "games" : [  
          {  
            "id" : 1,  
            "name":  "Super Mario 3",  
            "platform" : {  
              "id" : 1,  
              "name" : "NES"  
            },  
            "publishers" : [  
              {  
                "id": 1,  
                "name" : "Nintendo"  
              }  
            ]  
          }  
        ]  
      }]}  

I was reading about joins and subqueries, but so far I was only able to query for the top document. I could not run a query to say, find only the pages where a page type = 'ads' and the game.publisher = 'Nintendo'

I do get the id of the magazine, but I was hoping to get individual pages for this query. Should I just model Pages on a separate container?

Thanks

Azure Cosmos DB
Azure Cosmos DB
An Azure NoSQL database service for app development.
1,731 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Sajeetharan 2,261 Reputation points Microsoft Employee
    2022-11-02T18:59:25.11+00:00

    Yes you can achieve the result you need by using JOIN as below,

    SELECT
    f.number as Number,
    f.position as Position,
    g.name as Name
    FROM d
    JOIN f IN d.pages
    JOIN g IN f.games
    JOIN p IN g.publishers
    WHERE f.type = 'ads' and p.name ='Nintendo'

    However I would highly recommend you to reconsider the data modelling in this scenario, while embedding is a common scenario, if you think your nested array is going to grow in the future, be mindful that Cosmos DB has a limitation on the document size (2 MB for NOSQL API) , so it is ok to duplicate the document for each type of game. https://learn.microsoft.com/en-us/azure/cosmos-db/nosql/modeling-data

    While choosing multiple containers is also another option, but you might need to issue two queries on certain cases. Please follow the above documentation on the best practices


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.