Reputation: 1546
I'm doing my first project with MongoDB and from what I've seen the implicit creation of collections is the recommended practice (ie. db.myCollection.insert() will create the collection the first time an insert is made)
I'm using PHP and using different collections this way, but the problem is that I don't know where I should create the indexes I'll need for that collection. As I wouldn't know when a collection is created, the naive approach would be calling ensureIndex() just before every operation on that collection (which doesn't sound very good). Or whenever a connection to the database is made, make sure the indexes exist (what happens if I create an index on a collection that wasn't created? Is that defined?)
Any best practice advice for this?
Upvotes: 2
Views: 1137
Reputation: 93
Not sure if it's the best practice, but I tend to not put the ensureIndex in the app. I usually put the ones I am sure I will need using the db shell. Then I keep an eye during load testing(or when things start to slow down in production) and add any I missed again in the shell. You can build indexes in the background by doing ensureIndex({a : 1}, {background : true}), so building them later isn't as terrible as some other dbs.
MongoDB has a good profiler to find what is going slow: http://www.mongodb.org/display/DOCS/Database+Profiler.
10gen(MongoDB's commercial counterpart) has a free monitoring service that is talked about a lot although I haven't used it yet: http://www.10gen.com/mongodb-monitoring-service.
But as far as what happens when you call db.collection.ensureIndex() before collection is created, it will create the collection and put the index on it.
If you definitely want it in the app, I would go with the second option you put forth(ensure indexes right after db connect) instead of before each operation. I would probably save something in the db when I did so they don't run each time if there is more than a couple. Don't know php but here is pseudo code:
var test = db.systemChecks.findOne({indexes : true})
if (test == null) //item doesn't exist
{
//do all the ensureIndex() commands
db.systemChecks.insert({indexes : true})
}
Just remember to delete the systemCheck item if you find you need more indexes later to run through the indexes
Upvotes: 2
Reputation: 36784
Actually, ensureIndex() is exactly what you will need to do. I would do it in each Model's constructor that uses a specific connection - if you have one of those models). ensureIndex() will make sure that an index is only created when it doesn't already exists. You can alternatively do it when you create your database connection. If you run ensureIndex() on a non-existing collection, it would just create that collection and makes empty indexes (as there are no documents yet).
In the future, the PHP driver will also cache whether ensureIndex() was already run in the same request, basically making it a no-op: https://jira.mongodb.org/browse/PHP-581
Upvotes: 1