Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to store option data in mongo?

Tags:

mongodb

I have a site that I'm using Mongo on. So far everything is going well. I've got several fields that are static option data, for example a field for animal breeds and another field for animal registrars.

Breeds

Arabian
Quarter Horse
Saddlebred

Registrars

AQHA
American Arabians

There are maybe 5 or 6 different collections like this that range from 5-15 elements.

What is the best way to put these in Mongo? Right now, I've got a separate collection for each group. That is a breeds collection, a registrars collection etc.

Is that the best way, or would it make more sense to have a single static data collection with a "type" field specifying the option type?

Or something else completely different?

like image 443
taylonr Avatar asked Feb 21 '23 06:02

taylonr


2 Answers

Since this data is static then it's better to just embed the data in documents. This way you don't have to do manual joins.

And also store it in a separate collection (one or several, doesn't matter, choose what's easier) to facilitate presentation (render combo-boxes, etc.)

like image 67
Sergio Tulentsev Avatar answered Feb 24 '23 17:02

Sergio Tulentsev


I believe creating multiple collections has collection size implications? (something about MongoDB creating a collection file on disk as twice the size of the previous file [ db.0 = 64MB, db.1 = 128MB and so on)

Here's what I can think of:

1. Storing as single collection

The benefits here are:

  • You only need one call to Mongo to fetch, and if you can cache the call you quickly have the data.
  • You avoid duplication: create a single schema that deals with all your options. You can just nest suboptions if there are any.
  • Of course, you also avoid duplication in statics/methods to modify options.

I have something similar on a project that I'm working on. I have categories and subcategories all stored in one collection. Here's a JSON/BSON dump as example:

In all the data where I need to store my 'options' (station categories in my case) I simply use the _id.

{
  "status": {
    "code": 200
  },
  "response": {
    "categories": [
      {
        "cat": "Taxi",
        "_id": "50b92b585cf34cbc0f000004",
        "subcat": []
      },
      {
        "cat": "Bus",
        "_id": "50b92b585cf34cbc0f000005",
        "subcat": [
          {
            "cat": "Bus Rapid Transit",
            "_id": "50b92b585cf34cbc0f00000b"
          },
          {
            "cat": "Express Bus Service",
            "_id": "50b92b585cf34cbc0f00000a"
          },
          {
            "cat": "Public Transport Bus",
            "_id": "50b92b585cf34cbc0f000009"
          },
          {
            "cat": "Tour Bus",
            "_id": "50b92b585cf34cbc0f000008"
          },
          {
            "cat": "Shuttle Bus",
            "_id": "50b92b585cf34cbc0f000007"
          },
          {
            "cat": "Intercity Bus",
            "_id": "50b92b585cf34cbc0f000006"
          }
        ]
      },
      {
        "cat": "Rail",
        "_id": "50b92b585cf34cbc0f00000c",
        "subcat": [
          {
            "cat": "Intercity Train",
            "_id": "50b92b585cf34cbc0f000012"
          },
          {
            "cat": "Rapid Transit/Subway",
            "_id": "50b92b585cf34cbc0f000011"
          },
          {
            "cat": "High-speed Rail",
            "_id": "50b92b585cf34cbc0f000010"
          },
          {
            "cat": "Express Train Service",
            "_id": "50b92b585cf34cbc0f00000f"
          },
          {
            "cat": "Passenger Train",
            "_id": "50b92b585cf34cbc0f00000e"
          },
          {
            "cat": "Tram",
            "_id": "50b92b585cf34cbc0f00000d"
          }
        ]
      }
    ]
  }
}

I have a call to my API that gets me that document (app.ly/api/v1/stationcategories). I find this much easier to code with.

In your case you could have something like:

      {
        "option": "Breeds",
        "_id": "xxx",
        "suboption": [
          {
            "option": "Arabian",
            "_id": "xxx"
          },
          {
            "option": "Quarter House",
            "_id": "xxx"
          },
          {
            "option": "Saddlebred",
            "_id": "xxx"
          }
        ]
      },
      {
        "option": "Registrars",
        "_id": "xxx",
        "suboption": [
          {
            "option": "AQHA",
            "_id": "xxx"
          },
          {
            "option": "American Arabians",
            "_id": "xxx"
          }
        ]
      }

Whenever you need them, either loop through them, or pull specific options from your collection.

2. Storing as a static JSON document

This as @Sergio mentioned, is a viable and more simplistic approach. You can then either have separate docs for separate options, or put them in one document.

  • You do lose some flexibility here because you can't reference options by Id (which I prefer because changing option name doesn't affect all your other data).
  • Prone to typos (though if you know what you're doing this shouldn't be a problem).
  • For Node.js users: this might leave you with a headache from require('../../../options.json') similar to PHP.

The reader will note that I'm being negative about this approach, it works, but is rather inflexible. Though we're discouraged from using joins unnecessarily on MongoDB, referencing by ObjectId is sometimes useful and extensible.

An example is if your website becomes popular in one region of the world, and say people from Poland start accounting for say 50% of your site visits. If you decide to add Polish translations. You would need to go back to all your documents, and add Polish names (if exists) to your options. If using approach 1, it's as easy as adding a Polish name to your options, and then plucking the Polish name from your options collection at runtime.

I could only think of 2 options other than storing each option as a collection

UPDATE: If someone has positives or negatives for either approach, may you please add them. My bias might be unhelpful to some people as there are benefits to storing static JSON files

like image 30
nevi_me Avatar answered Feb 24 '23 18:02

nevi_me