Implementing Java Persistence with MongoDB and NoSQL Databases
Why NoSQL Databases?
Wow, opentaps Notes is such a useful application! If only I can use it to take notes on my
- Customers?
- Suppliers?
- Orders?
- Quotes?
- Products?
- Articles?
- Blog Posts?
- Recipes?
- Comic books?
The list goes on and on. The fact is, you probably want to write notes on any thing, don't you?
But a relational database is not so flexible. You have to define all the fields of your tables in advance, before you can use them. So, you're stuck with three options, each with their problems:
- You can define all the fields that your notes are related to. For example, you can add orderId, customerId, quoteId, productId, etc. fields on your Note field. This approach is either very limiting -- you can only use notes for those fields that you've defined here -- or very inefficient -- you will define hundreds of optional fields, most of which are never used. In either case, if you want to add a new field, you have to add a new field first.
- You can create a fully normalized data model with an additional table to join your Notes to things like customers, orders, quotes. (This is what the data model in opentaps 1.x does.) This is very flexible, but querying gets difficult very quickly. For example, it's easy to find all the notes of customer X or quote Y. But what if I want only the notes that are relevant to customer X and quote Y and order Z? Pretty soon you'll be creating a data warehouse for your notes just so you can do these queries.
- You can hack it by adding unspecified attribute-value pairs for your notes, and then tell yourself "Remember that attribute1 is order number, attribute 2 is customer number, etc." This may scale programmatically (Yay! No complex queries or nearly empty tables), but it won't scale programmer-matically (Did he say attribute 1 or 10 was order number? I thought it was attribute 10 too...)
Associating notes to other data is a trivial example. When you have a large scale enterprise system that combines data from many parts of your enterprise, choices like these would force either serious limitations or complexity, and often both, on the system.
This is where a NoSQL database like MongoDB comes in. Because it is schema-free, you are not constrained by an initial specification of the model. If new fields are needed, they can be added right away.
Accessing Your Data
To see the data you have stored, start a mongodb shell and do a query:
$ ./mongo MongoDB shell version: 2.0.6 connecting to: test > use notedb; switched to db notedb > db.notes.find().forEach(printjson); { "_id" : ObjectId("4fea13964728ec978c290124"), "noteId" : null, "noteText" : "test another note", "createdByUserId" : null, "userIdType" : null, "clientDomain" : "localhost", "dateTimeCreated" : ISODate("2012-06-26T19:55:02.542Z"), "sequenceNum" : NumberLong(1) } { "_id" : ObjectId("4fea13d64728ec978c290125"), "noteId" : null, "noteText" : "some note with many attributes", "createdByUserId" : null, "userIdType" : null, "clientDomain" : "localhost", "customer" : "555", "order" : "12345", "quote" : "98765", "dateTimeCreated" : ISODate("2012-06-26T19:56:06.611Z"), "sequenceNum" : NumberLong(2) }
See? In the second object, the attributes customer, order, and quote are stored as they were entered -- not as "attribute1, 2, 3", and not with other unnecessary attributes either.