我正在使用Salat和MongoDB,我正在尝试转换为自然键以避免重复数据库。我使用的案例类看起来有点像:
case class Foo(someRelatedId: String, email: String ...)
我想添加一个由someRelatedId + email组成的自然键,并让MongoDB使用它而不是默认的ObjectId。从文档中我感觉有可能,但我仍然在寻找一个有效的解决方案。这在很大程度上是由于我对Scala本身缺乏熟练程度,我敢肯定。
更新:我现在有一个有效的解决方案,但我仍然想知道这是否是最好的方式
case class Foo(someRelatedId: String, email: String, naturalKey: String)
object Foo {
def apply((someRelatedId: String, email: String) {
apply(someRelatedId, email, someRelatedId+email)
}
}
然后在package.scala中我映射到custom salat context:
implicit val ctx = new Context() {
val name = Some("Custom Context")
}
ctx.registerGlobalKeyOverride(remapThis = "naturalKey", toThisInstead = "_id")
这样我避免在我的域类中有一个强制的(无意义的)_id字段,但是我必须在伴随对象上重载apply(),这看起来有点笨拙。
答案 0 :(得分:5)
主要的Salat开发者。
像米兰建议的那样,为你的复合键创建一个case类:
case class FooKey(someRelatedId: String, email: String)
case class Foo(@Key("_id") naturalKey: FooKey) {
// use @Persist if you want these fields serialized verbatim to Mongo - see https://github.com/novus/salat/wiki/Annotations for details
@Persist val email = naturalKey.email
@Persist val someRelatedId = naturalKey.someRelatedId
}
object FooDAO extends SalatDAO[Foo, FooKey](collection = /* some Mongo coll */ )
如果您将“_id”作为字段名称,则可以在上下文中使用全局覆盖将“_id”重新映射为“naturalKey”,或者在每个对象上提供ad hoc @Key覆盖。
我个人不喜欢在模型中给_id一个不同的名称,因为你的Mongo查询必须使用序列化的密钥“_id”,而你的所有业务逻辑必须使用case类字段名称(“naturalKey”或其他) ,但是YMMV。
P.S。我们的邮件列表位于http://groups.google.com/group/scala-salat - 我会比Stack Overflow更快地看到您的问题。