Working with a tree-like data structure

I’m working on a computer science project comparing the performance of various databases for a simple Todo-App.

The key aspect is that To-Do’s are stored in a tree like structure, where one Todo can have zero or more Todos as children.

I’ve come across https://docs.mongodb.com/manual/applications/data-models-tree-structures/ where a few ways of doing this are presented.

My question is if there is a way to query (and modify) Todos stored in a User collection like this,
where a document of this collection has a property todos which stores a list of todos, and with todos under those in a children array. I hope the following document explains it better than i’m able to.

{
    "_id": {
        "$oid": "62347d38b8a4376e1bc67029"
    },
    "username": "Jan.Ntuli",
    "name": "Jan Ntuli",
    "email": "janntuli754@tiscali.net",
    "todos": [{
        "name": "Ducimus error voluptate consectetur quiaz.",
        "description": "",
        "moment": {
            "$date": "2022-04-20T21:40:50.638Z"
        },
        "priority": 29,
        "_id": {
            "$oid": "62347d38b8a4376e1bc67064"
        },
        "children": [{
            "name": "Maiores ullam repellat reiciendis, nz.",
            "description": "",
            "moment": {
                "$date": "2022-04-15T02:46:01.336Z"
            },
            "priority": 20,
            "_id": {
                "$oid": "62347d38b8a4376e1bc67065"
            },
            "children": [],
        }, {
            "name": "Nihil asperiores laborum aliquid ipsum a v.",
            "description": "",
            "moment": {
                "$date": "2022-03-24T03:49:36.894Z"
            },
            "priority": 20,
            "_id": {
                "$oid": "62347d38b8a4376e1bc67066"
            },
            "children": [{
                "name": "Est quasi error numquam,a.",
                "description": "",
                "moment": {
                    "$date": "2022-04-16T18:22:36.173Z"
                },
                "priority": 10,
                "_id": {
                    "$oid": "62347d38b8a4376e1bc67067"
                },
                "children": [],
            }, {
                "name": "Cum exercitationi.",
                "description": "",
                "moment": {
                    "$date": "2022-04-09T06:59:18.891Z"
                },
                "priority": 32,
                "_id": {
                    "$oid": "62347d38b8a4376e1bc67068"
                },
                "children": [],
            }, {
                "name": "Sed sunt dicta ipsum vel im.",
                "description": "",
                "moment": {
                    "$date": "2022-04-04T10:30:05.196Z"
                },
                "priority": 78,
                "_id": {
                    "$oid": "62347d38b8a4376e1bc67069"
                },
                "children": [{
                    "name": "Aliquid hic rerum fugit dom.",
                    "description": "Possimus consen.",
                    "moment": {
                        "$date": "2022-03-21T21:03:11.587Z"
                    },
                    "priority": 11,
                    "_id": {
                        "$oid": "62347d38b8a4376e1bc6706a"
                    },
                    "children": [],
                }, {
                    "name": "Vel aut qui quia cum. Magnam exercn.",
                    "description": "",
                    "moment": {
                        "$date": "2022-04-01T08:55:54.262Z"
                    },
                    "priority": 86,
                    "_id": {
                        "$oid": "62347d38b8a4376e1bc6706b"
                    },
                    "children": [],
                }],
            }, {
                "name": "Facilis quos omnis u.",
                "description": "Voluptate consectei.",
                "moment": {
                    "$date": "2022-04-13T17:06:12.311Z"
                },
                "priority": 5,
                "_id": {
                    "$oid": "62347d38b8a4376e1bc6706c"
                },
                "children": [],
            }, {
                "name": "Quia exercitap.",
                "description": "",
                "moment": {
                    "$date": "2022-04-03T23:48:30.433Z"
                },
                "priority": 29,
                "_id": {
                    "$oid": "62347d38b8a4376e1bc6706d"
                },
                "children": [],
            }],
        }],
    }],
}

The question is if it’s possible to, for example, find a todo with a certain name (“Quia exercitap.”) without knowing the depth it is at.

1 Like

Hi Johannes, welcome to the MongoDB Community!

To query and modify data in a Tree Structure, you can use $graphlookup. Take a look at the examples on this documentation page and try it for yourself!

1 Like

Hi!

Thanks for the hint; i think that i do understand the examples, the problem is that all of those are based on the approach of storing the relations explicitly and using an array. my approach was using a tree like document structure; i have hit a brick wall playing around with $graphLookup for this case.

Todo
  name
  todos: Todo[]

User
  username
  todos: Todo[]

This is basically my structure, but i have no idea of how to approach this.

Also a question would be if this tree like storing is even advantagous (performance wise) or if the “flat” storing like shown in the examples performance even better?

Thanks in advance!

Hi there,

First I want to mention you came out with a great question challenging MongoDB’s capabilities (in my opinion),
I for myself have a similar challenge also for the “tasks tree” structure.

  1. I think the key to understanding what is the best approach is first to know what will be the read and write queries on this.

  2. $graphlookup as you probably noticed is aimed to search todo by jumping between documents,
    if this query happens frequently or is aimed for performance it might be not an optimal solution.

  3. in Mongo, you should thrive to return as less documents as you can in each query, minimum writes, and filter from the document only necessary data.

so please be more specific about which queries you need except the “filter by name” you have mentioned.
example: do you need to fetch maybe all todos of a certain level of the tree? or immediate children of certain todo?