Never, ever, ever use MongoDB
cryto.net
cryto.net
Actually, I wrote a small "goodbye letter" to MongoDB on HN in the past:
"You got your chance, Mongo, and you screwed it up.
I tried getting the most out of you. I treated you like a princess, I indulged you, your wishes became my wishes and your thoughts were my thoughts. I stopped listening to all that criticism around you and thought of you as of a misunderstood child, even as you would refuse to do even the easiest tasks one could imagine.
I gave you everything there is to give, but you broke my heart. You left me in the most critical moments. I trusted you, but you would go your own way. Tears were shed and countless sleepless nights were to follow.
Remember that night you disappeared without leaving a sign? I sent you messages which got a response only after many hours. You didn't give a damn about my needs. Once, you told me: "it's not me, it's you". And I believed you, I truly did.
It's over now. It's been some time without you, and I'm getting better. I have discovered, that not everyone is like you. Some DBs care, they really do. You can trust them, they give you their everything.
I'm still struggling falling in love again, but it's getting better. Don't write me back. Goodbye."
Here's the link: https://news.ycombinator.com/item?id=8990754
https://pbs.twimg.com/media/CF9XvchWYAEKzTp.jpg
Source .sketch file is in:
https://github.com/mikemaccana/stickers
Joke is Alex Sexton's, I licensed font, designed, and printed them. Apparently a couple have found their way to Mongo HQ.
Also it stills remains one of the simplest databases to setup and use making it still my goto for hacks/spikes.
It's not hard to make it easy to do a thing in the wrong way - and that's exactly what MongoDB does. It doesn't make you set up authentication or table schemas, so it looks 'really easy to set up'.
In reality, though, you're wasting hours to save 10 minutes. Because at a later point, you're going to have your database broken into (if it can even be called that, without authentication), or you end up corrupting your data because two of your applications disagree over what the current object schema is.
To know how easy something really is, you need to compare how hard it is to set something up correctly. And once you do that, MongoDB falls far behind.
Of course, if you're at a company where those spikes find a way of turning into production code, then it's a different story.
Hacks that remain hacks in 100% of the cases, are rare :)
Why would I care about having my database broken into or even my data being corrupted for hacks/spikes. The very definition of these is that they are throwaway designed to test an idea before rebuilding in something more suitable.
And yes MongoDB is schemaless. That doesn't mean your data is going to automatically corrupt itself. You can just define your schema in some shared library. I can just as easily corrupt PostgreSQL if I change data types without updating the ORM.
No. There's no rule that says a prototype must be thrown away - often, it can be built upon further. See also https://news.ycombinator.com/item?id=9913563
> And yes MongoDB is schemaless. That doesn't mean your data is going to automatically corrupt itself. You can just define your schema in some shared library.
This doesn't work if there is no shared library, for example if you have two separate components in different languages both using the database. And at that point you're (poorly) reinventing a schemaful database anyway.
> I can just as easily corrupt PostgreSQL if I change data types without updating the ORM.
A good ORM will abide by your database schema - and no, you can't "corrupt PostgreSQl" by "not updating your ORM". It will, at most, error out because you're trying to work with non-existent columns.
In a schemaless database, there's no such thing as "non-existent columns", thus you can quietly corrupt data without realizing it.
And yes you can corrupt PostgreSQL. Change the data types without updating your ORM.
Eh, more complex and less secure the sqlite which if you want can store json as string values and provide full text search.
On the WAL level there's partial UPDATEs btw.
And we are using meteor (which is based on node)
Two levels: node and mongo == two levels of sadness.
(let the flames commence)
Edit: punctuation.
1) mongo's ability to have a live cursor that updates if the query returns new objects or changes within the objects currently being returned.
2) they have a minimongo which lives on the client. So code can do queries and not worry if the code is running client or server.
If meteor wasn't so tightly tied to mongo - I would hands down recommend it to a company doing node.js development.
Meteor is much easier than node to grok. ( no callback hell, no promises ) Meteor reads top to bottom the same as all the other languages out there. Node reads like a twisted spaghetti hairball that your cat vomited up.
So uhm, I don't agree that it's not good for prototyping; if your final code ends up having a decent abstraction level, it should not matter what you picked on day 1 anyway.
Unless the belief is "if it works on my laptop, it will work distributed across 50 nodes as well" is something you believe in (you shouldn't... without very good reasons).
I doubt that. As mentioned in the article, migrations with rollbacks basically solve this problem, and let you iterate through schemas quickly.
> Swapping it out for a real rdbms will mean changing a couple of classes anyway, nothing dramatic.
In theory, perhaps, but I have yet to see that in practice. I do freelance code review and tutoring for a living, and in every case I've seen, a significant amount of work would be needed to move to a different database.
Maybe so, but as I said above, they are another thing to do at a time when things are changing fast and one is more worried about checking whether the application "makes sense" than proving its correctness, so to speak.
> I do freelance code review and tutoring for a living, and in every case I've seen, a significant amount of work would be needed
Well, duh: if this weren't the case, you wouldn't have been involved in the first place :) What company calls consultants to review code they know how to fix themselves in a few minutes?
MongoDB is good if:
a) Your data model fits into the document model. Usually that means you'll be querying only one collection at time.
b) The access pattern of your application is a lot of READs and few writes. MongoDB has a collection lock, so it sucks for concurrent read/write operations.
c) If you need ACID support, your operations must be restricted to a single document.
If your problem fits on the restrictions above, you probably won't run into many problems. We've been using Mongo to store our authentication info, and to store payment transactions. No major problems so far, but our needs fit nicely into what MongoDB can provide.
Most of the rants I see are from people that got burned trying to use MongoDB as a drop-in replacement for a relational database.
I think Mongo is awful too, and I'm sure there are problems with this approach - I'd love for someone with more DB knowledge to go into details - but saying there are 'no relations' seems to be an oversimplification.
Mongoose is also very much not the default MongoDB client in Node.js - it's a third-party client library by Automattic. The official client according to the MongoDB documentation is `mongodb` (https://www.npmjs.com/package/mongodb), which does not feature relations.
Thanks for your excellent explanation and totally understood re: not being able to optimise for relationships on the server.
I once started consulting on a Rails app project which used MongoDB. But I was never able to get productive: I had my development environment all set up, but then the code wouldn't work with the development database. I pinged the other dev:
"Oh, I made changes to the data model. I'll zip up and email you a new copy of the dev database."
This continued for a couple of iterations and I had to quit the project because I could never continuously get work done.
The issues I listed provably exist. That you haven't run into them yet doesn't change that - and quite likely, you might not even know whether you've run into it.
Losing data or having your database open to the wide internet, for example, are two scenarios that you will likely not be aware of unless you explicitly test for them.
> I've got nothing against relation databases but there are not a solution to every single problem.
And if you'd read my post carefully, you would've seen that I make no such claim. They do solve many problems, however.
> Heck, why not decide first if you can use flat files?
Flat files are rarely the correct solution. Race conditions ahoy!
> Do you really need to query and join. Not all problems require that sort of thing.
Many do. And even if they don't, MongoDB is still not the right choice.
1. The bugs that MongoDB historically suffers from are those that are unlikely to occur for most people, but when they do cause the most suffering. This is a combination of them being incredibly hard to replicate, but more insidiously that the system keeps working, it just has a small data corruption. This can obviously lead to huge problems down the line. The conclusion is firstly that just because you haven't seen a problem doesn't mean there isn't one, but also just because there isn't a big problem for you doesn't mean there won't be one in the future.
2. Databases have some of the most demanding testing around, due to the important requirements placed on them. There's a really good talk floating around from a guy at FoundationDB. The sorts of bugs that keep cropping up in MongoDB are the sorts of bugs that level of testing would find, which is a very bad smell. Thus, one should only resort to MongoDB if no other solution is reasonable.
But in reality, for most tasks something like Postgres (with JSON additions) or CouchDB etc is equally suitable and easy to use. This means that most new users of MongoDB can actually afford to use a better/less buggy database, they just choose not to.
3. Flat files are generally a silly idea mostly because of the additional tooling that databases give you. ORM systems make using a database much, much easier than using flat files, and the databases usually allow easy analytics. They also typically give better error messages, better performance, better extensibility etc. If it comes time to move your data into the cloud, you'll have a much easier time of it if you use a database etc. It's a win-win in almost every case.
However, I believe there's a few existing options for using postgres - https://github.com/numtel/meteor-pg
In fact it's the reason I'm not using Meteor, which is a shame because it looks really good. The optimistic UI feature is something I really want, and have had to implement my own custom solution for. I've nothing against Mongo per se, I just need a relational database.
Since most apps are likely better suited to using a relational database, I'm curious as to Meteor's original decision to go with Mongo. Would love to know their rationale behind that choice if anyone can enlighten me / point me towards any articles?
Meteor.js is a fantastic development system (if you can live with needing sticky sessions and you need its features).
The package is really just a simple wrapper around an npm library.
Because meteor is node-based any db that node has libraries for can be "used" .... at the expense of giving up on most meteor features.
Take it up with the Meteor.com people.
[0] - http://info.meteor.com/blog/whats-coming-in-meteor-12-and-be... [1] - https://news.ycombinator.com/item?id=9811583
For example: The message warning you that 32bit builds are not safe for storing more than 2GB of data is larger than the download button itself. If don't see this, you should probably be not in charge of storing any data anyways.
Many other issues have been resolved with the 3.0 release or are documented very clearly.
2. It's a dumb limitation, and an architectural issue as far as I'm concerned.
3. It still doesn't justify silently throwing away data for years.
4. Many of the points on my list remain unaddressed, and likely never will be addressed.
EDIT: Additionally, the typical system administrator doesn't install MongoDB from the 'Downloads' page, but uses a package manager, and thus never sees the warning even if it's there.
Warnings like this belong in all the relevant spots in the documentation, not just on a download page.
https://github.com/mongodb/mongo/commit/b3322b86a014683018ac...
There's plenty in Mongo to complain about, but grousing about the 32-bit limitation just makes you look like you're bad at reading introductory documentation.
This was the case until as late as 2014: https://web.archive.org/web/20140704182658/http://www.mongod...
And again, the 'download' page or README is not sufficient for such a warning, nor is a startup message a reliable place to put it (because of initscripts and such). It should have been in all the relevant places in the documentation, instead.
It was certainly in the documentation, in the blog posts, in the startup logs, and in the README for quite a long time. If you missed it, it's probably because you weren't paying attention. Again, there are plenty of good reasons to dislike MongoDB, but this isn't one of them, and harping on it substantially degrades your credibility.
All the wrong places, as already stated. These are not the places where developers actually look. I provided some better example locations here: https://twitter.com/joepie91/status/622920351731843072
> [...] in the blog posts [...]
Certainly not there. Go look around for MongoDB tutorials from the timespan where unacknowledged writes were the default, and almost none of them remark on the 32-bits limitation.
> If you missed it, it's probably because you weren't paying attention.
Nonsense. It simply wasn't in the locations where people actually look. You can easily verify that using the Wayback Machine (and in fact, this is still mostly the case today).
> Again, there are plenty of good reasons to dislike MongoDB, but this isn't one of them, and harping on it substantially degrades your credibility.
If pointing out extremely dangerous past negligence from the MongoDB developers "degrades my credibility" in your view, then you have some very strange ways to determine credibility.
If you're not reading READMEs, installation notes, and server logs and instead depend on marketing splash pages to highlight the limitations of the technologies you use, you're a bad developer. Sorry.
> Certainly not [in blog posts]
http://blog.mongodb.org/post/137788967/32-bit-limitations
> It simply wasn't in the locations where people actually look. You can easily verify that using the Wayback Machine (and in fact, this is still mostly the case today).
I first started using Mongo in 2010 according to my gitlogs (after it having been on my radar for some time before that), and I very distinctly remember reading about the 32-bit limitation well before I'd ever installed it, because we were also using Varnish at the time, which has similar issues on 32-bit systems because it too uses (or at least, at that time used) memory-mapped files.
The claim that the limitation was not documented well, or was hidden, or was generally unknown at that time is just simply false.
If you were checking getLastError on your writes, you would see the write fail when you ran out of address space.
Bad defaults? It was defended as "this is ok because system is distributed" and there was a joke about it helping ace all the silly benchmarks. So it wasn't "oops we forgot to uncomment out the fsync line in the code". It was a deliberate decision.
It was deceptive, and that is why many people hate MongoDB and wouldn't let it get even close to their data -- because have a track record of lying about the capabilities of their system.
That's all well and good, but reporting writes as successful and silently failing when your data ticks over 2 GB instead of throwing errors or doing something useful like that is more what the complaint is about. Obviously, you could set up monitors on your data storage and alarm if it reaches 1.75 GB, but if you're mature enough to do that, you're mature enough to use a real database solution.
For MongoDB's actual limitations, read aphyr's Call Me Maybe series.
Also, it's not like Postgres even tries to offer clustering. So what are you comparing Mongo to? There's no reason to believe that a single-node Mongo instance will be any less reliable than a single-node MySQL or Postgres. At least, nobody has presented that argument.
Seems like a lot of other companies are too (Eg. Viber) Here's a video from their tech team explaining the reasons behind the switch: https://www.youtube.com/watch?v=R5JpRrMJVIA
Does MongoDB allow SQL queries? I didn't know that, but then again, I guess I don't care either. I haven't looked at Mongo in a couple of years after deciding not to use it. I do recall liking the query syntax from the class though.
I haven't messed with JSON features in PostgreSQL yet and have no idea how they work. That's next.
It's not without its problems but ES's first-fifteen-minutes story is pretty good.
ES is amazing for what it does, but its use cases don't overlap heavily with Mongo (or RDBMSes).
Evidence for those claims that MongoDB is "fast" never materialized, nobody really knew where the claim came from, yet it was constantly repeated. They sponsor a lot of hackathons, and so on.
Source: my last employer used MongoDB, and switching to an RDBMS would have forced us to rewrite ~80% of the codebase.
Also, when people say NoSQL they actually mean MongoDB.
That's just not true. There are tons of NoSQL solutions that are well known. Redis.
Edit: In the sense that there are many, many well-regarded and used NoSql databases.
PostgreSQL has supported JSON for a good while now, I've even explicitly linked to it in my post. And no, MongoDB is certainly not 'as good' - many of the problems listed simply do not exist in PostgreSQL.