Quick-and-dirty unique constraints in Raven DB
Raven DB, like most NoSQL databases designed to be fast and scale out, does not readily support enforcing uniqueness of fields between documents. If two users must not share the same email address or Facebook ID, you cannot simply add a unique constraint for it.
However, Raven DB does guarantee uniqueness in one place: each document must have a unique ID, or a ConcurrencyException
will be thrown. By creating dummy documents with say, an email address for an ID, this feature can be effectively exploited to achieve unique constraints in Raven DB.
You can easily add this behaviour to your database if you install the Raven DB UniqueConstraints Bundle, which will enforce uniqueness on updates as well as inserts. However… if the field is immutable and you just want something quick and dirty you can use this: RavenUniqueInserter.cs 🙂
using (var session = documentStore.OpenSession()){ var user = new User { EmailAddress = "[email protected]", Name = "Richard Dingwall" }; try { new RavenUniqueInserter() .StoreUnique(session, user, p => p.EmailAddress); } catch (ConcurrencyException) { // email address already in use }}
It works by simply wrapping the call to DocumentSession.Store()
with another document – in this case, it would also create a document with ID UniqueConstraints/MyApp.User/[email protected]
, guaranteed to be unique.
You can grab it here: https://gist.github.com/1950991