1

Fellow programmers. Is it considered as a bad practice to use such MongoDb model:

{
    companyId: '',
    companyName: '',
    companyDivisions: [
        {
            divisionId: '',
            divisionName: '',
            divisionDepartments: [
                {
                    departmentId: '',
                    departmentName: ''
                },
                ...
            ]
        },
        ...
    ],
},
...

Because right now it's getting complicated to update certain departments.

Thanks.

websanya
  • 171
  • 1
  • 14

1 Answers1

3

I don't think this is a bad practice generally speaking. If your model resembles this data structure it is a good choice storing data this way, leveraging a document database. You can naturally handle data and most likely you have a direct map onto your data model.

Another choice would be to have three different collections:

  • companies;
  • divisions;
  • departements.

However, in this case you would end up storing data as you would do in a relational database. Thus, more than a general rule, it is a matter of data model and expected query profile on your database.

Edit: using MongoDb 3.6+

Using your document oriented approach, a single department can be granularly updated using the following update:

db.companies.findAndModify(
{
    query: {
        "companyId": "yourCompanyId"
    },
    update: {
        $set : { "companyDivisions.$[element1].divisionDepartments.$[element2].divisioneName": "yourNewName" }
    },
    arrayFilters: [ 
        { "element1.divisionId": "yourDivisioneId" },
        { "element2.departmentId": "yourDepartementId" } 
    ]
});

This update uses the new powerful filtered positional operator feature introduced by MongoDB v3.6. The $[<identifier>] syntax allows to select an array entry based on a specific condition expressed in the arrayFilters option of the db.collection.findAndModify() method.

Note that in case the condition matches multiple array items, the update affects all such items, thus allowing for multiple updates as well.

Furthermore, note that I would apply such an optimization only in case of need, since premature optimization is the root of all evil. (D. Knuth).

Marcello
  • 879
  • 6
  • 20
  • In my legacy schema (this database was actually a .dbf file converted to .json and imported to mongodb) the `departmentId` is not unique. So in every division there is a department with `departmentId` equal to 1. So in my case I need to make multiple conditions (e.x. if `divisionId` equals to 528 then set a new name for a department with `departmentId` equals to 2 or pull this department completely). I guess what I need to do is to send an entire document of company with changes from front-end (Vue.js app) and update it in the Database. Am I right? – websanya Feb 25 '18 at 07:39
  • 1
    Retrieving a whole document in order to update a part of it is a normal practice in a document database. You end up using your database as a data bucket and your code remains extremely *domain oriented*. Thus, it might even be considered desirable. As far as performance issues, you can perform hundreds or even thousands of such updates per second, with relatively small documents, datasets and normal hardware. Should you incur in database/network bottlenecks, then you have to stick to a more granular update strategy, avoiding transferring entire documents back and forth. – Marcello Feb 25 '18 at 13:44