At E-butik, we’re always looking to improve the performance of our stores, and one of the ways we’ve recently found is by using MongoDB for storing products. Because we have a great deal of flexibility in our products, storing them in a RDBMS tends to require queries with a lot of joins, and that can be slow. MongodDB however, due to it’s schema-less nature is built for that kind of flexibility. Said and done, we implemented a transition of our products to MongoDB using Doctrine’s MongoDB ODM, and indeed it provided a great performance boost in our stores.
Of course, when we started to transition products to MongoDB we also started thinking about what else could and should be in there. Since we have the products in there, it makes sense to have the cart in there, and the best way to have the cart in there is to have the session in MongoDB too.
Native or not
When it comes to sessions in PHP, you generally have two options. Either you work with the built-in sessions by using session_set_save_handler, or you roll your own. Symfony2 provides a lot of help in both scenarios, you have the NativeSessionStorage, which in turn have different subclasses that use different session save handlers, or you could implement SessionStorageInterface, and do your own thing.
While there would have been many upsides (the amount of code needed, for one) to extending NativeSessionStorage, we had one requirement, which this approach couldn’t solve. We wanted to be able to embed other Documents in the session. Extending NativeSessionStorage, all of the session data is serialized. Storing the session in a non-serialized fashion gives us queryability and more options for picking a good shard key. Being able to embed documents provide performance boosts since it allows better hydration on demand.
Needless to say, we opted to roll our own sessions.
Ladies and gentlemen…
Please allow me to present EbutikMongoSessionBundle!
It’s licensed under the MIT license. Configuration is simple, you might need to choose which document manager to use (it defaults to the default document manager), and you need to change the session storage service to ebutik.mongosession.storage.
Scalars and arrays recursivly containing only scalars are stored as native Mongo datatypes. Embedded document implementing the SessionEmbeddable interface (which doesn’t contain anything, it just declares that the document is intended to be embedded in the session) are embedded, and other types are serialized.