0

我目前正在使用 reactivemongo 和 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]) {    
}

这个对象代表一个用户。用户总是有一个名字,并且可能有一个电子邮件或手机号码。

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)

我插入一个带有名字和电子邮件的用户信息。其余字段为无。

现在是我不知道如何处理的部分。由于 None 写入 null,所以 null 值保存在我的用户信息集合中。我尝试插入相同的名字和电子邮件,这应该会失败并且确实会失败,但原因是错误的。就我而言,原因是为 jakob 和 null 创建了一个索引:

DB operation failed: [message=DatabaseException['E11000 duplicate key error index: userinfos.$userInfo.userInfo.mobile_1  dup key: { : "jakob", : null }' (code = 11000)]]

据我了解 sparse 仅适用于缺失值,并且由于 null 是一个值,因此 sparse 在这种情况下不起作用。那么我应该如何处理呢?是否可以使用可能为空的值创建索引?或者我应该以其他方式处理我的 None 值吗?也许我可以更改写入,以便如果 None 写入空 [T] 参数。MongoDB 的处理方式是什么?

4

0 回答 0