Skip to content

Instantly share code, notes, and snippets.

@srenault
Forked from playxamplez-admin/CODE
Last active December 20, 2015 02:59
Show Gist options
  • Save srenault/6060165 to your computer and use it in GitHub Desktop.
Save srenault/6060165 to your computer and use it in GitHub Desktop.
Flatten #json object for partial update with #ReactiveMongo #play2.1
def flattenObject(obj: JsObject, prefix: Option[String] = None) :Seq[(String, JsValue)] = {
obj.fields.toList match {
case ("$date",_) :: Nil if prefix.isDefined => Seq(prefix.get -> obj)
case ("$date",_) :: Nil => throw new Exception("Can't save $date at the first level.")
case fs => fs.flatMap { t =>
val name = prefix.map(_ + ".").getOrElse("") + t._1
t._2 match {
case obj: JsObject => flattenObject(obj, Some(name))
case value => Seq(name -> value)
}
}
}
}

Updating specific fields of a Mongo document.

Requirements:

  • You use ReactiveMongo & PlayReactiveMongo.
  • You speak directly to Mongo with JSON.
  • You want to update specific fields of a document.

Here, the Mongo document I will use for my explaination :

  {
    "personal": {
      "name": "RENAULT",
      "firstname": "Sébastien"
      "address": {
        "number": "2",
        "street": "Saint-Pierre",
        "city: "Chartres"
      }
    }
  }

You want to update only those fields:

 {
    "personal": {
      "name": "Renault",
      "address": {
        "number": "2"
      }
    }
  }

If you set the original document with this partial document, you will loose some data (firstname, city, street). To not loose any data and update only specific fields, you have to set the document with the following document :

  {
    "personal.name": "Renault",
    "personal.address.number: 2
  }

The JSON Object is flattened. The belonging code do the work by flattening a JSON object to this special form.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment