Was MongoDB Ever the Right Choice?
simplethread.com
simplethread.com
I have worked with at least one company that had been built using MongoDB as a primary data store from day one. This caused untold pain later on, but the trade-off is that it likely allowed the company to exist at all – the founder being more of a domain expert than a technical expert, but being able to use it to scale their idea pretty quickly without having to pay much attention to all that tedious "reliability" and "safety" nonsense :)
That said, it's not something that an experienced developer should be using for anything nowadays, and the solution might be to ensure that competing alternatives (like Postgres) can learn from why MongoDB became popular and seek to solve some of the pain points in their own implementations.
Every time we wanted to do something new a founder would say "Domino can do this!" and then they would spend the whole weekend setting it up for what we were trying to do.
All because we were some kind of IBM partner and they wanted to please the big wigs.
One day, and despite my protests, I had to bin our perfectly fine and well maintained/loved Exchange server for fricken Notes/Domino just because one of the investors had some free licenses. After the migration, everyone hated it and I was persona non grata seeing as it was me who had to switch us over. It never worked properly. I left not long afterwards and the poor sod who was my replacement had the joy of looking after that dumpster fire.
edit: opening sentence
The flip side of this is that beyond a certain size such initial designs are a killer. And a company should monitor time sunk into maintaining such things, prioritize those that are most expensive and fix them as soon as it can afford to. And this is often done way too late, causing harm that can be impossible to repair. My 2c.
At one point, there was some discussion about migrating one of our systems to a document store. There was a fair bit of back-and-forth at first. After someone pointed out that Lotus Notes is basically a document store, though, the idea was dropped more-or-less immediately and unanimously.
I can see the attraction when you're just starting out on a project, but we had just spent way too much time dealing with what they're like after they've had time to mature into full-blown quagmires.
Why not? You've said a lot of stuff, but haven't really backed it up with any reasons other than anecdotal experience.
Maybe the additional work is too much for the benefit, but it's not that there's no benefit. Forgoing the guarantees usually leads to much more extra work. I think Python's "no types anywhere" was a reaction to Java's "types everywhere", but neither is optimal. Something with gradual typing or type inference has much more bang for its buck, so whenever I see "I use MongoDB because there's no schema to worry about", I always think that it's going to come back and bite someone in the ass.
To nitpick, Python actually came before Java. But, the overall sentiment is something I agree with.
On the other note, I keep seeing people recommending Postgres, but to me that is apples vs. oranges. Just because it has json storage doesn't make it a replacement. How much effort and money a company needs to keep a replicated Postres cluster vs. Mongo? In one of my previous jobs we had to hire a consultant to do that. With Mongo pretty much any experience dev could do that.
My personal view is that MongoDB's main advantage is its flexibility. It allows teams to shape and evolve the product as needed. When specific features/parts require new solutions, new solutions can be used (financial transactions, etc). Features that allowed us to leverage what we have instead of researching new tools were:
1. Schemaless - Logic is in the app; Gives visibility; Can be tested; Less migration headaches; Easier to evolve your architecture.
2. Indexed arrays, attributes (name, value pair) - Allows to be more creative (add tagging system to any type of data you have)
3. Aggregation - basic BI could be done from day one, which business can get value sooner.
Of course, everyone's millage varies
We (ZeroTier) experienced the same thing but with RethinkDB, a similar schema-less database. We outgrew it when we needed something more solid and more reliable and we had a pretty settled schema.
There seems to be a cost associated with evaluating optimal paths. Personally I get SQL (well enough to use it) and I can work with so I don't bother with MongoDB much, but if there's someone who doesn't and needs to get a project going and the alternative is lots of delay or no project, yeah why not.
I feel like when it comes to development people really gripe about the best choices ... when the non best choices might just as well be looked at as a path to the best choices, and there's a lot of value in that.
Now that's all within the context of weighing the costs to ... everyone. Hobby project few if anyone will see, hey who cares. Work project, a lot more diligence and consultation with others ;)
I know this but I keep ignoring it ¯\_(ツ)_/¯
I've gotten time to make something polished and perfect and came out with "uh you know that first run prototype ... might be better in some ways".
Fortnite uses MongoDB for everything, they have a huge load ( 7.5M CCU is insane ) and don't have more problems than if they choose something else.
MongoDB gets bad press on Reddit / HN probably because of past marketing campaigns, but nowdays it's a very solid solution.
Or you can just use Citus.
You might have a case in which you need something faster – I'd argue that there are still better solutions, but YMMV.
An experience developer understands when the goal is to deliver something as fast as possible vs building something more resilient.
If you're building an internal tool, particularly one that won't be storing data that would later be used for analytics, there's absolutely no reason to not go with mongodb over a relational database considering you can get hosted versions of both for the same price. For a less than a week long project, you could be saving at least 20% of the time spent not having to worry about a datamodel.
You are not "not worrying about a datamodel" – you are just ignoring the data model that exists. And that overhead, if it exists at all, is far less than "20%".
s/datamodel/data-mapping/It's a combination of factors. I still mostly reach for more traditional SQL options (including SQLite). It just depends on the needs of the application, the costs associated and the skill and experience of the developers working on the application.
I would still reach for Mongo first for a handful of application types, I do wish that RethinkDB had the marketing effort/money/skill that Mongo did, as I think they were more solid on the technology, and the admin interfaces are great. I'd love to see a mid-scale vendor pick up the tech and run with it.
Everybody else I know, however, has had nothing but headaches.
They’re the same reasons I’ve seen people fail at using Cassandra, Redis, or Spanner. If you can’t adjust to the limitations and paradigm shift, you get no benefits. And an ORM often makes everything worse.
The “no” in NoSQL doesn’t seem to stop people from modeling join relationships in Redis, or chaining distributed queries with fully consistent writes on Cassandra.
I’m on a project right now, where a developer has selected an ORM for PostgreSQL that forgoes joins. They’ve managed to generate about 100 queries, in one case, where a single query is all that’s needed. 2ms vs. 800+ms. That individual is incapable of using something more complicated. Substituting Mongo as-is will make everything worse, and they’ll triumphantly proclaim how terrible NoSQL is and then write an article.
I feel confident using Mongo for any task. I don’t feel confident letting most of my peers use it.
There are a LOT of legitimate gripes, but no article I’ve read mentions them. It’s always the same superficial complaints from ten years ago. If you can’t get past those, choose another tool. End. Of. Story.
As an appeal to authority I would like to mention that I have relevant vocational qualifications on the subject (more geared towards scalability and operations). Although I don’t believe it really matters - it will to those who assume I don’t understand best practice.
MongoDB itself is not /really/ a valid choice in many scenarios that it was painted as solving. Their only fault is overzealous marketing, it has (in my opinion) very clear pain points that should be avoided, but those painpoints are antithical to why many people used it in the first place.
Most people pick up mongo because it’s painted as being “beginner developer friendly”, I don’t mean new developers, I mean picking it up and running with it, without understanding it, was made to be incredibly easy. But MongoDB itself needs you to understand your data patterns before you start adding shards, so the technology itself depends on you actually sitting down and designing an architecture while understanding that. These goals are at odds with each other.
In MongoDB (as it was when I was using it in full prod 6+ years ago) you -needed- to understand how your data is going to grow and how it will be queried long before you ever created an index. You could not grow after creation. But using it as a plain document store with no searching and heavy sharding on the document ID is the best way to go. And in that scenario it is much better than most competitors.
In nearly every /other/ scenario its a less favourable choice than another technology of some variety.
I would argue the data loss point but I think if that’s not a solved issue it will be, and I’m fairly certain you can configure it to be slower but correct (my memory is bad).
I am not a MongoDB advocate, nor do I hate the technology outright. I strongly dislike how it was marketed as being a panacea.
And for the same reason I avoid PHP, I will attempt to avoid MongoDB.
(As in; it can be done well but the majority of cases will be poorly implemented)
I guess it's actually lying now that I think of it. People might be justified in being a little bit peeved.
But people don’t seem to understand that there are plenty of scenarios where you really either don’t know the schemes in advance and/or the “schema” is defined by an external source.
I worked for a company that sold software that allowed users to create forms that could be filled out either on the web or via a mobile app.
The user created the form and the schema and the indexes were created on the fly - one collection per type of form. What would an RDMS have bought us?
For context, I've previous experience with NHibernate, EF, EF Core, Dapper and some others from yesteryear - Marten is probably the best dev experience I've had from an ORM.
This would fit in a single SQL query which is expected to perform reasonably well, with an unstructured database optimizing this query will take months of work.
If you can know for sure from the start that you'll never need queries like this, then of course something like Mongo will be awesome. But requirements change, hence this article.
At another company where I worked where we used Postgres, we had a multitenant set up where each of our (large) customers had their own database. The issue would have been the same.
You would no more “scan over all of your data” with Mongo with indexed fields than you would with an RDMS with indexes.
As requirements change, you do need to migrate your data into a schema that makes sense and that's regardless of whether you're using SQL or MongoDB.
In fact, if you are using C#. You could use the same LINQ syntax either way.
db.formEvent.aggregate([
{ $match: { createdAt: {$gte: ISODate("whenever")}}},
{ $group: { _id: "$custId", userAgents: { $addToSet: "$metadata.userAgent" } } },
{ $sort: { createdAt: -1 } }
])
Something like this? I'm not sure why this couldn't be an optimized query in mongo, but I'm also not sure why a query like this one needs to be optimized? This would run fast enough without needing indexes, and really fast with an index on a couple fields, but is a query like this run so frequently you need to have it be extremely optimized?> What would an RDBMS have brought us?
It would probably work using a forms table, fields table, submissions table, and values table.
It would probably work using a forms table, fields table, submissions table, and values table.
I didn’t ask “would it have worked”, I asked “what would have bought us”.
Maybe I don’t follow. You would insert a row into the fields table. Millions of rows should be fine.
> I asked “what would have bought us”.
I don’t know. None of this matters really, as long as the service works.
On any good RDBMS, adding a nullable column to an existing table is an O(1) operation. This is the only option that's comparable to what's available in MongoDB, and it has the same performance characteristics.
On the great ones, adding a non-nullable column with a default value to an existing table is also an O(1) operation. The good-but-not-great ones, it's also O(N). (As always, you get what you pay for.) For MongoDB, wanting to do this would be unusual, but you would have the option of back-filling every record. It would be an O(N) operation, too. So, for this case, the characteristics of the RDBMS are no worse, and possibly better.
Adding a non-nullable column with no default is always O(N), but the fact that you're suggesting a document store as an alternative implies even more strongly that this is not the use case you're trying to cover. That said, if you did do it, it would also be O(N).
Converting a numeric column to a string column is always going to be O(N), yes. Whether or not that's the better option is something that's got to be decided in context. Basically, do you want to pay the cost of datatype conversion in one lump sum and then be done with it forevermore, or do you want to pay a small fee for datatype coalescing every time you access that field? There are good reasons to choose both options. However, all too often, the 2nd option is chosen for a very bad reason: Simply assuming that it's zero cost.
I work a lot with documents in my current role which includes a lot of JSON structures as well.
MongoDB has been immensely useful for a team with limited scope (and requisitional abilities within the organization) to get up and running and store backups of documents that have been processed and JSON API responses.
I definitely wouldn’t apply it as a panacea, either.
Like any tool, it has it’s place in the belt for me. It’s no universal hammer, though.
Is Mongo the right tool to build your entire business on top of? Probably not, but it can be the best tool for the right job.
We use it as an event database which collects over 100M+ semi-structured records daily with about 200 (and growing) different schemas... It keeps 1.5TB of records in the collection which is achieved using the invaluable capped collection function, and we can index the structured fields very easily. We also pipe the data into elastic for quick kibana querying but just that step requires a lot of index partitioning and mapping to work smoothly.
I also feel that a significant amount of mongo's power lies in the aggregation pipeline which is often ignored and which can replace entire ETLs, sending the compute to the data can be much more efficient in a lot of use cases.
All this runs for us on some relatively cheap (compared to 1.5TB of high i/o RDS) commodity hardware, running 3 replicated nodes. More complex ETL jobs or Hadoop users can pull data from mongo selectively and quickly - spark has a way to partition a query into N threads based on a provided key achieving line rate data pulls even from a single node.
Throw in compression on disk and in-flight and you get something that is really compelling. We've all run out of disk on a database before, it's never fun.
My one gripe is the learning curve for new developers. I do find that once leveraged, I see a lot more data being stored when it's as simple as nesting an object into your main object and saving it, which data teams like.
Depends on your use cases, but really, it's been an invaluable tool so far.
Elastic is great in it's own sense, but it's not as flexible as mongo when it comes to schemas.
The query language is verbose but I would hesitate to call it a nightmare. You can always search using the Lucene query language, and SQL support is landing sometime soon.
We always verified basic correctness with a new database by inserting several billion geometries as fast as the database would accept them, reading the entire data set back out, and comparing it to the original data set we inserted for any discrepancies. MongoDB never passed this test. It would apparently lose records semi-randomly every time, so we removed it from the test set. It was the only database we tested that had this issue.
> MongoDB 3.6.4’s sharded clusters offer comparable safety to non-sharded deployments.
These tests are now integrated into MongoDB's regular test suite. Maybe MongoDB wasn't the right choice for you at the time you were evaluating it, but I just want to point out that MongoDB has matured and improved a great deal.
(Disclaimer: I work for MongoDB)
Perhaps in another decade, MongoDB can shed its well-earned reputation for eating data.
Kind of in line with the article, I think that people should methodically check what works for them... particularly for something as serious as a database. It would be a shame if somebody decided against using something because they heard about an issue that has been fixed and/or improved in more recent versions.
Why should they, though? The fault here is on its management team. Users and clients lost their trust, for good reasons.
I never used MongoDB, but I know people that got in real trouble due to it.
I accept that the unacknowledged writes was a bad decision, but IMHO if you deploy a new database without reading the documentation, you have bigger issues.
The reality is that there are some places where speed of movement is important and referential integrity is just not that big a deal. We're not all building banking systems.
If you gave to answer "it depends" on a "was ist ever", you should have written "yes" instead, imo.
2. You can go from strict guarantees to looseness safely, when you demonstrably need to. The reverse isn't true -- it's easy to wind up realising, much too late, that you actually needed particular guarantees that you didn't even think of.
Relational databases didn't become incredibly popular by accident. It's because they were a drastic improvement -- theoretically and empirically -- on the generation of NoSQL databases that preceded them.
A lot of things “become popular” but that doesn’t necessarily mean they are good.
I’m bringing up C# again...
Querying with Mongo using the Mongo driver in C#....
var people = db.GetCollection<People>().AsQueryable();
var seniorMales = from p in people where p.Age >= 65 && p.Sex == “M” select p;
Querying an RDMS with EF: var people = context.People;
var seniorMales = from p in people where p.Age >= 65 && p.Sex == “M” select p;
Both queries get translated to their respective query languages and run on the server. C# enforces the types in either case and you get compile time type checking and IDE Intellisense. In either case you can index the Age and Sex fields.NoSQL databases aren’t “schemaless”. Mongo understands the schema of JSON data and can query against it just like an RDMS understands rows and columns.
If you are just using one table with two fields (id/value and value contains a json object that changed) for logging perhaps a relational database isn't the right choice. Redis might be better / mongo might be better depending on what comes next.
Let's stop the next cycle where everyone moves to postgres for everything only to throw it away for the next thing. I was using postgres in 2008 and it was great.. why did it take until 2019 for everyone else to discover? We are in the peak postgres cycle. I hope it doesn't get disgarded when the serverless hype kicks into gear.
Too bad GlobalsDB went nowhere...
The product I work on has ~400 tables active at the moment, and ~800 that have ever existed in it over the last 6 years. We depend on the database schema to reduce complexity at the application level.
I don’t think the complexity would be manageable at the application level if we couldn’t do this. At least not with the ~6 engineers working on it.
Our data is indeed simple and beside data collection via a web app, the focus is on reports with that data; but always in small sensible junk and never across the whole available data for a model.
I might be wrong about that because I pretty much ignored DBs in the late 90's and 00s, so I never really followed what was happening. However, one thing I'm absolutely sure about: MongoDB had very few features that were really novel. I'm not really sure why people think everything started there (especially someone who knows about 4GL ;-) )
The only "advantage" to JSON is that it maps directly to the object trees most developers use in their scripted programs (which is misguided IMHO).
It had to deliver three kinds of formats: CSV, JSON, and XML.
JSON was a one-liner, then came CSV and then XML.
But all the consultants working in customer projects said CSV was the most important one because it's industry standard.
When the consultants sent me example CSV files from like 5 customers I couldn't believe they all had a different format.
> Loss of transactions
MongoDB 4.0 supports ACID transactions: https://www.mongodb.com/transactions
> Loss of relational integrity (foreign keys)
> Having a database enforce these relationships can offload a lot of work from your application, and therefore from your engineers.
I've never seen anyone use MongoDB without also using something like Mongoose where you get all this for free. Zero work for your engineers. https://mongoosejs.com/
> Lack of ability to enforce data structure
Again, Mongoose. The work doesn't fall on your engineers, it falls on an awesome, heavily-used, heavily-tested library.
> Custom query language
Can you give an example of something that you realistically would want to do in SQL that you can't with a JSON query?
> Loss of tooling ecosystem
This might be the only valid caveat in the entire article.
Custom query language - I bet he also hates ElasticSearch. But again, using C# and the first party Mongo LINQ library, you are working with LINQ - the same built in C# query language that every C# developer should be familiar with. One of the requirements I wrote when I was hiring contractors for a Mongo based project was familiarity with Entity Framework. Even though we wouldn’t be using EF, if they knew it, it would be seamless to transition over to Mongo/LINQ.
Edit:
And as a side note, creating your “application defined schema” from a pre-existing JSON document, is a simple matter of copying the JSON to:
But I would never use a weakly typed language and a weakly typed data store. That’s a mess waiting to happen.
I'm of the opinion to let the "awesome, heavily-used, heavily-tested" RDBMSs built to manage data and constraints do just that.
I may have misread your comment but rarely do more than one client application access a database. Especially in today's often Microservices architecture. So using a library as mentioned is fine. And as the app evolves/gets rewritten you can keep the library or replace it with a similar one.
Over 10+ years ago I did join a few projects with existing architecture that had evolved to multiple applications accessing the same database. And they were a nightmare but that is rare to encounter these days as most people have learned that one app = one DB. (Data warehousing is a possible exception, but mostly those datasets are exported instead as well as streams for machine learning).
Probably preaching to the choir but multiple clients mean feature freeze/deadlock, no DB refactoring and spaghetti architecture.
That has not been my experience!
Sorry if my comment came across as a criticism of your post. It was more targeted at the long threads of people bashing MongoDB, thinking the caveats are still relevant/accurate today. Because they really aren't – MongoDB is a completely valid choice of database today.
ACID transactions were added over a year ago, and Mongoose is almost as old as MongoDB itself.
Can you define joins in terms of each other? Otherwise, any join that isn't left outer join ($lookup) can't be represented in an aggregate query AFAIK.
I'm not that deeply familiar with MongoDB first-hand. Is Mongoose something you can bring to bear as a plugin on the database server? Or is it strictly a client application library?
Because to analogize to relational databases:
* If you cite PL/SQL, T-SQL, PL/pgSQL, etc as solutions for SQL's shortcomings, then you have a point.
* But if you point to JPA/Hibernate, Entity Framework, SQLAlchemy, or just raw hand-rolled application-tier logic, then that's no counterpoint at all. Because it means that only one client can safely use the database, and that assumption breaks down in the real world beyond the toy proof-of-concept stage.
For me, Mongoose is actually another argument against MongoDB. It's basically trying to add basic functionality on top of MongoDB, that most RDMS already have.
And no, it does actually not "all of that", just some of it. Just an example: Mongoose would still let you delete a user, while all of the related posts are remain with broken references to that user.
> Can you give an example of something that you realistically would want to do in SQL that you can't with a JSON query?
Sure everything can be done, it's just clunky and hard to get right. This graphic perfectly summarises the horror of writing simple queries in MongoDB: http://twiki.org/p/pub/Codev/TWikiPresentation2016x07x14Mong...
I've been using Mongoose in production for several years, 2011-2014 and again for the last 12 months, within teams of 4-8 developers. The amount of engineering, bug fixing and testing was definitely higher in MongoDB than with MySQL or Postgres.
Once I got to work with MySQL and Postgres after 2014, I found it so much easier to query for the data I'm looking for and to ensure data strong consistency, mind you, even without any use of a library!
> Mere newness bias – Many software developers tend to undervalue technologies they have worked with for a long time, and overvalue the benefits of a new technology. This isn’t specific to software engineers, everyone has the tendency to do this.
> Feature-positive effect – We tend to see what is present, and overlook what isn’t there. This can wreak havoc when working in concert with the “Mere newness bias”, since not only are you inherently putting more value on the new technology, but you’re also overlooking the gaps of the new tech.
This is so much what I've always wanted to and tried to say on the topic. Adopting new technologies thoughtfully rather than reflexively is something I'd love to find out about a team before joining one again.
I work at MongoDB, so I do want to mention that MongoDB has changed a lot over the past few years. MongoDB now has multi-document ACID transactions. Also, schema validation means you can enforce a strict data structure if you want. On top of that there have been improvements in data durability and consistency (the Jepsen tests are now integrated into the MongoDB test suite).
As mentioned in the article MongoDB has matured a great deal. It's far more mature and fully-featured in 2019 than it was in 2012.
> Does this tool solve a real problem for us > Do we thoroughly understand the tradeoffs
Well, no. But neither did running JS on the server (along with numerous other similar examples). I've used MongoDB plenty of times before (in production with 1 issue to date) and I absolutely will again.
Huh? Enough people apparently knew JavaScript well enough that running it on a server was really useful. Why's that not a real problem? (Not being able to do so.)
The problem was that the "velocity" blocking requirements could be completely arbitrary, and could be anything a merchant required as long as they used any of the data that was available from the transaction/previous transactions - block a transaction if it's more than 500 GBP and we've had 3 other transactions greater than 500 GBP in the same country in the previous 10 minutes.
This essentially meant we would either have to do dev work whenever a merchant had a new "velocity" rule, write our own complex framework to handle the addition of arbitrary rules, or just stuff the data into a schemaless NoSQL store and then leverage the power of the engine's query syntax as part of the merchant's configuration.
We went for the schemaless NoSQL solution and we used mongodb v1.6 - around 2010 IIRC, before it reached peak hype, before it "fixed" a lot of the out of the box defaults, before it got a lot of hate. It worked perfectly and ran from the time we deployed it until i left the company a few years later. Maybe I left a mass of technical debt, but the solution ended up being so simple and so little code I doubt it.
The other nice thing was that the velocity system was not essential - if the time to do a velocity check took more than 0.05s we would ignore it. If the backend wasn't responding we ignored it. If the write to the storage failed it didn't matter. We didn't need to keep more than a couple of hours worth of data. If we lost all of that data it didn't matter.
I don't know if I'd take the same approach now, nine years later, but at the time the use of mongodb worked perfectly. It was only a couple of weeks work, and solved the problem elegantly. So in response to the original question: yes, but as usual RTFM and make sure the pros and the cons fit your use cases.
The problem we were trying to solve was that allowing, essentially, arbitrary queries against the main database had the potential to cause problems because we would have to ensure that those queries were optimal and all the relations were correct before we allowed those rules to be put into place - i.e. more dev and DBA work and potentially schema changes (addition of more indexes, etc).
It was far easier to have an ephemeral duplicate of the transaction data with a flat structure, a single key value document, as that mitigated the risks and removed the aforementioned problem.
The velocity system was essentially a firewall in front of the main database server - this was one of the main requirements, the velocity system must not have any affect on the load of the main transaction system. We could have added another db server, but that would have put us on the route to more servers, more complexity, etc, as we were self hosting at the time.
In other words, you claim it worked for years, but anything would if you can lose all data, reboot it, have no real-time requirements, etc.
In summary, it is not really a useful data point on whether MongoDB is useful or not.
Within reason. If the failure rate is 1 in 1000 then it's probably not as a big a concern as 1 in 10 depending on your use case
> In summary, it is not really a useful data point on whether MongoDB is useful or not.
As I said in the last sentence - it worked perfectly. In other words the "no guarantees to provide" never actually came up and I don't recall us having any data loss, response time, or write issues.
If you get to the point where your website is outgrowing it’s initial mongodb implementation, you have a very good problem on your hands.
Some features that don't scale are very nice to have when you don't have scaling issues. For example, if you add tags to your documents and you want to query on those tags (find all documents containing tag A and B), it's nice that's just a builtin.
I haven't found a single datastore that is as developer friendly that supports that use case, so for now, I'm sticking with mongodb for my pet project.
(if you know of a datastore that has support for this query out of the box, please let me know)
https://firebase.google.com/docs/firestore/query-data/querie...
But also, PostgreSQL supports arrays, so you can have much more native tags as well, and it can be indexed and searched in a more traditional SQL fashion.
I have only used this with Django ORM, but I believe it's pretty straightforward if my memory is correct.
CREATE TABLE documents (name text, tags text[]);
INSERT INTO documents VALUES ('Doc1', '{tag1, tag2}');
INSERT INTO documents VALUES ('Doc2', '{tag2, tag3}');
INSERT INTO documents VALUES ('Doc3', '{tag2, tag3, tag4}');
SELECT * FROM documents WHERE tags @> '{tag1}';
name | tags
------+-------------
Doc1 | {tag1,tag2}
SELECT * FROM documents WHERE tags @> '{tag2}';
name | tags
------+-------------
Doc1 | {tag1,tag2}
Doc2 | {tag2,tag3}
Doc3 | {tag2,tag3,tag4}
SELECT * FROM documents WHERE tags @> '{tag2, tag3}';
name | tags
------+------------------
Doc2 | {tag2,tag3}
Doc3 | {tag2,tag3,tag4}
Postgres certainly isn't perfect, but it's usually a good answer to "how do I store and query data" where you don't have any particular specialist requirements.As I already use MySQL in many projects, I do much the same thing with MySQL's json support.
I believe json is now supported by Sqlite too.
Basically, if you already have an up-to-date relational database, then the chances are you can already use it as a sane document store.
Just saying, so nobody reading the threads thinks they have to go grab some new database if they are already using one!
1. As a cache, like redis 2. As a log store, like Elasticsearch
In both cases, the data is somewhat ephemeral, and not the "source of truth" for the app. The minute it is used for holding real, customer supporting data, things start to get dire real fast.
(Disclaimer: I work for MongoDB)
(Disclaimer: I hate MongoDb)
At the time, I concluded that MongoDB was the "Visual Basic of Databases." It was very easy get something simple running, much like Visual Basic classic was.
Quite honestly, something ACID-compliant with a MongoDB-like API is really needed for small-scale projects and prototyping.
https://news.ycombinator.com/item?id=19492562
Here was my comment from yesterday morning:
>Question 1: What problems am I trying to solve?
I wish I had really thought about this when I first wrote my largest web scraper. At the time, I was still relatively new to database design and programming in general. This web scraper, out of the thousands I've written in the interim, is--of course--the one that is still going strong many years later.
I eshewed MongoDB for all the reasons given to me on the internet and, because I was slowly gaining competence with SQL, ended up building a large and complex pipeline to send the data right into Postgres. In retrospect, this was a serious design mistake, and one that I regret the most.
Although I still contend that the data did eventually need to be normalized, I now believe that I was doing it far too early. By ingesting the JSON stream into a parser, splitting it up, generating foreign keys, and then forcing the whole works into a single Postgres database I severely limited the capacity of my web scraper (and also guaranteed the need for a very powerful server to run it).
Had I initially dumped all results into MongoDB (or some other efficient document store) and then, separately, parsed the output into normalized SQL, I would have dramatically simplified the operation, maintenance, and debugging of my web scraper. Plus it would have been much simpler to spawn work jobs on to different machines instead of trying to break up huge monolithic processes with poorly defined endpoints. There have been many lessons learned.
In short, Mongo likely serves a very good purpose for high-speed data storage and manipulation (although it's hardly alone in this space). However, it's still likely not a great all-around solution and works best when supported by an ACID-based normalized RDBMS. Unless, of course, things have dramatically changed in recent updates.
The main reasons I chose Couch over something relational like MySQL was essentially 1. to have a a clear path for data to go as JSON from server/API/client without the need for mapping, 2. Schemaless to allow for quick iterating and development, 3. Easy to start with local first development and then rollout for deployment. Also, I hadn't worked on a stack with a persistence strategy that was solely document oriented so it was a fun and good learning experience.
A few things I learned along the way:
I still needed to create externalized "views" of the data that either combined data from multiple documents and the need to hide private data. I still needed to serve lists of data in pages. More importantly I needed to provide a lot of adhoc reporting over the various data I'm storing across multiple Couch dbs.
The views and paging are all easily solvable with Couch, but so much easier to implement using SQL and it feels like I'm just pushing that need or compensating somewhere else in the implementation. But the friction around quick reporting has made me second guess choosing Couch/document based vs. something like a MySQL/ORM.
The author's point of the custom query language (Mango for Couch) and loss of tooling ecosystem has been the biggest problem for me on this project and I'm considering migrating to a Node/Sequelize/MySQL stack just to avoid wasting future cycles trying to quickly report on the data I'm storing. When the project started the reporting aspects weren't as apparent as they are today since the project has evolved and other requirements became necessary.
If anyone has any experience or recommendations for tools that can easily do adhoc reporting against CouchDB or documents in general I'm interested in hearing about them.
I believe Mango will automatically create the view index on the fly for any query you make and save the index for later. Before CouchDB 2.0 this would usually have to be done manually before the query was run.
Once you understand the way that views and map/reduce work, it's super powerful for doing large scale statistics on data sets quickly. Only thing that I wish for is a Mongoose adapter for couchdb so I can use it as a backend for when an open-source project wants to use MongoDB (Looking at keystone.js for example)...
This is such a problem. Just yesterday someone came to me and said, "We're now using x to do y. It makes z a lot easier. Just wanted to let you know so you can make the appropriate changes to your analysis & reporting applications."
Say what now? I'm embedded within the operational unit. I know a lot about day to day operations in & out of the systems in use, and how they ultimately translate through in data. I asked half a dozen questions, and 4 of them were met with "oh, we hadn't thought about that." These are deal-break questions, things the current method handled without issue, so much so they became invisible to the users, until they decide to make a change and realize the new method doesn't make any provision for them.
Today we use PG everywhere with JSON, though still the library support for JSON in Mongo is often a little bit better than in PG drivers.
The main problems I have had with MongoDB were that, as of several years ago, it did not integrate well with most (I would argue any in practice) data reporting / displaying third parties.
Also, some of the more advanced queries were not at all intuitive. In fact, I barely remember any of the syntax now. In Mongo's defense, that might have to do with the fact that we atempted some stuff in MongoDB that we would never attempt to do with SQL cursors.
I'm far from a SQL expert and have mostly done client-side work in my life, but SQL-based database does seem like a good match for things like these. You just need to write more foreign key relations, and constraints are a bit more complicated, but I see no reason to switch to NoSQL for things like these.
Foreign references? They've got them. https://docs.mongodb.com/manual/reference/database-reference...
ACID transactions? They've got them. https://www.mongodb.com/transactions
There are countless stories of odd performance issues, occasional data loss, and similar.
postgresql can handle JSON documents with none of that and better performance. If you're not doing a lot of relational work, relational databases shard really nicely for arbitrary scalability. etc.
I love the concept of Mongo, but when I used it, I found it unusable. I switched back to relational databases as well as S3. On the whole, it just works better.
I know MongoDB supports references, but it's like using a flathead driver for a Phillips head screw.
ShopWiki is a shopping price listing site, where it keeps tracks of prices for any item: computer, clothing, food, etc. ShopWiki needs to be able to store, access, AND search amongst all of these different items. So, MongoDB is the perfect solution.
If the application being built has similar requirements to ShopWiki or a retail site where it sells _everything_, then MongoDB IS the right choice, because the founders basically built MongoDB for ShopWiki.
To sum it up: Is MongoDB the right choice? If the product is similar to ShopWiki, then yes.
Once the data layer starts to resonate around a solution ... then pick the right horse for it.
Honest question: what's wrong with just defining a domain model, adopting an ORM and a serialization framework, and simply go with a conventional RDBMS? Afaik all reference web application frameworks handle this right out of the box.
With an enforced schema you will at least know that all of the existing data matches the schema. Without it you have to hope that you had zero bugs while collecting the terabytes of data.
If you've a schema, you sometimes need to rewrite an entire table as part of a migration, and that can mean heavy engineering if you want to avoid downtime or disabling writes during the migration. There are 1:1 relationships between tables in the wild that wouldn't have passed a sniff test as part of an early schema design review, but then got created regardless to avoid a lengthy table rewrite.
If you've no schema proper, by contrast, you can manage multiple variations of what the data might look like in code. Not that such a thing is simple; it's definitely not, for the reason you raised. But it's simpler to deploy and migrate, or certainly might appear to be so to someone who isn't comfortable with SQL.
Also, there's a class of apps where having a schema doesn't add much value and NoSQL actually makes sense. Think storing and mining logs, scraped data, ML training sets, etc. -- apps where it doesn't matter much however a big pile of data gets stored, so long as you can shovel through it in parallel or store it very fast.
And most ORMs suck outside of LINQ based ones since they aren’t a part of the language.
I can't just make calls from Html + JS to Postgres.
But I can with MongoDB
RDBMS to me is to expensive in the churn and I've run into some deadly query scenarios.
As a non-storage expert I would just love one of those 2000's era 'object databases' to start with. We used to use them a lot in networking because they suited well to topology. I'm not sure they're much of a thing anymore however as I suggest JSON DB's are pretty close to it so there's no need for it.
But they fit developer's mentality really well.
I think a lot of the “beef” people have towards MongoDB is from past experiences where it was used in this regard.
I usually use PostgreSQL at this point, but when I use MongoDB, it’s more as a “document store” than a “database.”