Lefrog February 2016

Arangodb: Best modelling strategy to reference leaf in a tree like structure

Given a fix 3 levels deep tree structure like

collection: tree

{
    "name": "Level 1",
    "children": [{
        "name": "Level 1.1",
        "children": [{
            "name": "Level 1.1.1"
        }, {
            "name": "Level 1.1.2"
        }]
    }, {
        "name": "Level 1.2",
        "children": [{
            "name": "Level 1.2.1"
        }]
    }]
}

And in another collection reference a "leaf" node:

collection "person"

{
  "name": {
    "first": "John",
    "last": "Doe"
  },
  "linkToLeaf": "<need to reference a leaf node. e.g. 'Level 1.2.1'>"
}

And will need to query data to:

  1. render the tree so admin user can organize hierarchy (basic CRUD page)
  2. display in some place the breadcrumb "You are in: Level 1 > Level 1.2 > Level 1.2.1"
  3. establish link to "leaf node"

Using arangodb, what's the best way to model the data? Using graph, simple JSON documents, mix of both, something else?

I'm working on a new project and we want to make the jump to NoSQL but coming from background of traditional RDBMS I would simply model the tree using a recursive join and therefore and simply reference the "leaf node" using it's primary key.

Not sure how to do it Arangodb...

Answers


dothebart February 2016

There are several points that should have influence on your data model:

  • as in regular databases, joins don't come for free. Aggregating data from several collections into one document can be helpfull.
  • depending on what you want to update working with deeply structured documents can become challenging and produce hard to read AQL.

In your example you show something that seems very self similar, nested like a fractal. You can for shure make this flat, and do what you did nested via graph traversals. This can be benificial for your code on the client side, and you will not only be bound to a fixed number of layers; Graph traversals produce a very nice behaviour and you can even iterate deeper dynamical.

The new ArangoDB pattern matching traversals could look like that:

db._create("names");
db.names.save({_key: "Level1"});
db.names.save({_key: "Level1.1"});
db.names.save({_key: "Level1.1.1"});
db.names.save({_key: "Level1.1.2"});
db.names.save({_key: "Level1.1.3"});
db.names.save({_key: "Level1.2"});
db.names.save({_key: "Level1.2.1"});

db._createEdgeCollection("nameEdges")
db.nameEdges.save("names/Level1",   "names/Level1.1",   {layer: 0})
db.nameEdges.save("names/Level1.1", "names/Level1.1.1", {layer: 1})
db.nameEdges.save("names/Level1.1", "names/Level1.1.2", {layer: 1})
db.nameEdges.save("names/Level1.1", "names/Level1.1.3", {layer: 1})
db.nameEdges.save("names/Level1",   "names/Level1.2",   {layer: 0})
db.nameEdges.save("names/Level1.2", "names/Level1.2.1", {layer: 1})

db._create("persons")
db.persons.save({_key: "adam_ant", details: {cname: "adam", lname: "ant"}})
db.persons.save({_key: "david_bowie", details:
    {cname: "david", lname: "bowie"}})

db._createEdgeCollection("nameToPersons")
db.nameToPersons.save("names/Level1", "persons/adam_ant",
    {himself: true})
db.nameToPersons.save("names/Level1.2", "persons/david_bowi 

Post Status

Asked in February 2016
Viewed 3,060 times
Voted 9
Answered 1 times

Search




Leave an answer