One may miss a very important detail: you're using Mongo. It's not an RDBMS, it's a document-oriented DB and it should be used differently.
Namely, where a relational DB would use a foreign key (a reference, in fact) and rely on joins with indexes, you can embed entries right into your users' documents, RDBMS are terrible at doing so. A tradeoff, yeah. I personally think it's a better choice, read on and see if you agree.
Of course, that implies that once copied from the game-wide colection, the player's item is no longer linked to its "prototype item". Thus, should the prototype change, changes to it won't propagate to its copies (unless you explicitly spend time doing that). That, in turn, makes each copy self-contained. You mentioned upgrading certain items -- piece of cake, just increment a field on an object in player's inventory and there you have it. All other items like this one are not affected.
By using SQL-style data structure (a table with all items, a join table items-players) you'd end up with a ridiculous amount of lookups on Mongo's side, so the database in this case may quickly become a performance bottleneck. If that looks better suited for your needs (i. e. if you plan a lot of many-to-many relations), consider switching to PostgreSQL, it has some highly unusual datatypes for a relational DB (hstores, arrays) that may help.