Mongodb – How to handle “or” possibilities in MongoDB

database-designdocument-orientedmongodbschema

I'm new to MongoDB and by no means an expert in DB design in general. This feels like a really basic question that's probably been answered a million times, but I'm having a surprisingly hard time finding an answer for it: is there a good way to easily handle either/or choices in the DB, or structure it in a way that makes it easy to deal with in code?

Let's say I'm building a cocktail database in MongoDB. I'm adding the entry for a Manhattan.

  • 2 oz. Bourbon or Rye Whiskey (this is the issue)
  • 1 oz. Sweet Vermouth
  • Dash Aromatic Bitters
  • Garnish Maraschino Cherry

So I might do a cocktails collection with an entry like:

{
    "_id" : "1234",
    "name" : "Manhattan",
    "ingredients" : [
        {
            "measure" : "2 oz.",
            "ingredient" : "Bourbon Whiskey"
        },
        {
            "measure" : "1 oz.",
            "ingredient" : "Sweet Vermouth"
        },
        {
            "measure" : "Dash",
            "ingredient" : "Aromatic Bitters"
        },
        {
            "measure" : "Garnish",
            "ingredient" : "Maraschino Cherry"
        }
    ]
}

Which is fine, but how do I get the rye in there? I don't think I'd want to do "ingredient" : "Bourbon or Rye Whiskey", would I? Is it better for the purpose of searching, later, to have them separated out? What's the best practice, here?

Also, an even more tricky drink would be something like a Martini, where I would actually use a different garnish for vodka than I would for gin, so I'd want to give the user the option to choose the base liquor they're working with and then give the proper garnish accordingly.

Any suggestions? Thanks!

Best Answer

In cases where there is a legitimate option to use a substitute ingredient you can do one of several things, all involving storing the option in the ingredients array. One way could be to add a field to an array element as "allowedSubstitutions": "different liquor" another way would be to turn "ingredient" into an array which lists possible different acceptable ingredients.

However, in case of a tricky martini drink, I would strongly encourage you to store two separate drinks, one called "Martini" and the other called "Vodka Martini" otherwise known to purists as "not really a martini" :)

The real key question is how will you be querying this collection - with flexible schema the way you use the data will usually drive the way you structure its storage, not the other way around.