A lot of applications these days use a NoSQL database as a result of unstructured data, write scalability, and so on. MongoDB is one such database. According to its website (http://docs.mongodb.org/manual/core/introduction/):
MongoDB is an open source document database that provides high performance, high availability, and automatic scaling.
Key features of MongoDB are:
High performance
High availability (automatic failover, data redundancy)
Automatic scaling (horizontal scalability)
ReactiveMongo is a Scala driver for MongoDB that supports non-blocking and asynchronous I/O operations. There is a plugin for the Play Framework called Play-ReactiveMongo. It is not a Play plugin but it's supported and maintained by the team of ReactiveMongo.
This section requires prior knowledge of MongoDB, so please refer to https://www.mongodb.org/.
To use it, we need to do the following:
libraryDependencies ++= Seq(
"org.reactivemongo" %% "play2-reactivemongo" % "0.10.5.0.akka23"
)
conf/play.plugins
:1100:play.modules.reactivemongo.ReactiveMongoPlugin
conf/application.conf
:mongodb.servers = ["localhost:27017"] mongodb.db = "your_db_name" mongodb.credentials.username = "user" mongodb.credentials.password = "pwd"
Alternatively, use the following:
mongodb.uri = "mongodb://user:password@localhost:27017/your_db_name"
Let's see usage of the plugin with a sample application. We may come across an instance in our application where we allow users to monitor activities on their devices in the form of heat sensors, smoke detectors, and so on.
Before using the device with our application installed on it, the device should be registered with this application. Each device has ownerId
, deviceId
, its configuration, and product information. So, let's assume that, on registration, we get a JSON in this format:
{ "deviceId" : "aghd", "ownerId" : "[email protected]" "config" : { "sensitivity" : 4, …}, "info" : {"brand" : "superBrand","os" : "xyz","version" : "2.4", …} }
Once a device is registered, the owner can update the configuration or agree to update the product's software. Updating software is handled by the device company, and we only need to update the details in our application.
The queries to the database will be:
Insert
: This query includes registering a deviceUpdate
: This query includes updating device configuration or informationDelete
: This query occurs when a device is unregisteredSelect
: This query occurs when an owner wishes to view the details of the deviceUsing Reactive Mongo, the device registration will be:
def registerDevice(deviceId: String, ownerId: String, deviceDetails: JsObject): Future[LastError] = { var newDevice = Json.obj("deviceId" -> deviceId, "ownerId" -> ownerId.trim) val config = (deviceDetails "configuration").asOpt[JsObject] val metadata = (deviceDetails "metadata").asOpt[JsObject] if (!config.isDefined) newDevice = newDevice ++ Json.obj("configuration" -> Json.parse("{}")) if (!metadata.isDefined) newDevice = newDevice ++ Json.obj("metadata" -> Json.parse("{}")) collection.insert[JsValue](newDevice) }
In this snippet, we've built a JSON object from the available device details and inserted it in devices
. Here, the collection is defined as follows:
def db = ReactiveMongoPlugin.db def collection = db.collection("devices")
The insert command accepts the data and its type:
The db operations for fetching a device or removing it are simple,def fetchDevice(deviceId: String): Future[Option[JsObject]] = { val findDevice = Json.obj("deviceId" -> deviceId) collection.find(findDevice).one[JsObject] } def removeDeviceById(deviceId: String): Future[LastError] = { val removeDoc = Json.obj("deviceId" -> deviceId) collection.remove[JsValue](removeDoc) }
This leaves us with just the update query. An update is triggered for a single property of configuration or information, that is, the request has just one field and its new value is this:
{ "sensitivity": 4.5}
Now, a query to update this would be:
def updateConfiguration(deviceId: String, ownerId: String, updatedField: JsObject) = { val property = updatedField.keys.head val propertyValue = updatedField.values.head val toUpdate = Json.obj(s"configuration.$property" -> propertyValue) val setData = Json.obj("$set" -> toUpdate) val documentToUpdate = Json.obj("deviceId" -> deviceId, "ownerId" -> ownerId) collection.update[JsValue, JsValue](documentToUpdate, setData) }
When we wish to update a field for a given document in MongoDB, we should add the updated data to the $set
field in the query. For example, an equivalent MongoDB query would be as follows:
db.devices.update( { deviceId: "aghd" ,"ownerId" : "[email protected]"}, { $set: { "configuration.sensitivity": 4.5 } } )
3.15.18.198