3
votes

I've a MongoDB collection where I want to store documents like this:

{
    "_id" : ObjectId("52d14842ed0000ed0017cceb"),
    "details": {"name" : "Pankaj" , "email_id" :"[email protected]"}
}

But unfortunately here insert into mongo like this:

{
 "_id" : ObjectId("52d14842ed0000ed0017cceb"),
 "details" : { "name" : "\"Pankaj\"", "email_id" : "\"[email protected]\""} 
}

Why this slash coming into mongo! How to remove this slash?

In my code "details" store in Map[String,String]. And here is how I insert a document:

//BsonDocument
var document = BSONDocument()
details.foreach(e => {document = document.add(BSONDocument(e._1 -> BSONString(e._2)))
    }
2
You are inserting a JSON string instead of a sub document. You have to create an associative array(javascript object) in order to insert a subDocument. otherwise it will just create it as a JSON string - Brian Noah
You have " char inside your string values, for whatever reason not related to Mongo. - cchantep

2 Answers

1
votes

You need to convert what you need to insert into a BSONObject. Otherwise, it will be treated as a String.

0
votes

As for ReactiveMongo 0.12 the conversion is automatic, but the provided converters only support simple immutable maps with String type as a key, so take into account this cases that will need an extra push to work with the provided ReactiveMongo converters like with this samples:

  • To store m:Map[Long, String] you'll need to flattened as (m.map { case (k, v) => (k.toString -> v) })

  • To store m:Option[Map[String, String] you'll need to flattened as m.getOrElse(Map())

  • To store m:collection.mutable.Map[String, String] you'll need to flattened to immutable map with m.toMap()

  • And of course if you have a m:Option[collection.mutable.Map[String, String] you'll need to flattened as m.getOrElse(Map()).toMap()

If you're using an older version of ReactiveMongo or if you need something more specialized (or you just want to play with the Scala types) you can play with a custom converter like:

  def convertMapToBsonDocument[T](m: Map[String, T])(implicit writer: BSONWriter[T, _ <: BSONValue]): BSONDocument = {
    m.foldLeft(BSONDocument()) {
      case (doc, (key, value)) =>
        doc.merge(key -> writer.write(value))
    }
  }

NOTE: this custom sample code works with ReactiveMongo 0.12, if you are using an older version, try to change merge for add or to skip the implicit writer declaring T directly as a String (or the class/classes you need)