我正在玩activemongo和mongodb,我发现了一些我不知道如何处理的事情。
假设我有一个案例类 UserInfo :
case class UserInfo(override var _id: Option[BSONObjectID] = None,
firstName: String,
lastName: Option[String],
email: Option[String],
mobile: Option[String],
fbId: Option[String],
fbPublish: Option[Boolean]) {
}
此对象代表用户。用户始终是firstName,可能有电子邮件或手机号码。
object UserInfo {
import play.modules.reactivemongo.json.BSONFormats._
implicit val userInfoReads: Reads[UserInfo] = (
(__ \ "_id").read[Option[BSONObjectID]] and
(__ \ "firstName").read[String] and
(__ \ "lastName").read[Option[String]] and
(__ \ "email").read[Option[String]] and
(__ \ "mobile").read[Option[String]] and
(__ \ "fbId").read[Option[String]] and
(__ \ "fbPublish").read[Option[Boolean]]
)(UserInfo.apply _)
implicit val userInfoWrites: Writes[UserInfo] = (
(__ \ "_id").write[Option[BSONObjectID]] and
(__ \ "firstName").write[String] and
(__ \ "lastName").write[Option[String]] and
(__ \ "email").write[Option[String]] and
(__ \ "mobile").write[Option[String]] and
(__ \ "fbId").write[Option[String]] and
(__ \ "fbPublish").write[Option[Boolean]]
)(unlift(UserInfo.unapply))
}
在UserInfo配套对象中,我定义了UserInfo的写入和读取。 插入此文档时,UserInfo将保存到我的Mongo实例,而None的字段将保存为null。 由于我有很多用户,我想在 firstName + email 上设置索引,在 firstName + mobile 上设置第二个索引:
ensureIndex(List("firstName" -> IndexType.Ascending, "email"-> IndexType.Ascending), unique = true, sparse = true)
ensureIndex(List("firstName" -> IndexType.Ascending, "mobile"-> IndexType.Ascending), unique = true, sparse = true)
我使用firstName和email插入UserInfo。其余的字段都是None。
现在是我不知道如何处理的部分。由于None写入null,因此null值保存在我的userinfos集合中。我尝试插入相同的firstName和电子邮件,这应该失败,但确实如此,但出于错误的原因。我的理由是有一个为jakob和null创建的索引:
DB operation failed: [message=DatabaseException['E11000 duplicate key error index: userinfos.$userInfo.userInfo.mobile_1 dup key: { : "jakob", : null }' (code = 11000)]]
据我所知,稀疏只适用于缺失值,因为null是一个值,稀疏在这种情况下不起作用。 那我该怎么处理呢?是否可以创建值为null的索引?或者我应该以其他方式对待我的None值?也许我可以改变写入,如果None写空[T] param。 MongoDB处理这个问题的方法是什么?