Каков наилучший способ иметь дело с составными ключами при использовании Salat с MongoDB?
Я использую Salat с MongoDB и пытаюсь конвертировать в натуральные ключи, чтобы избежать дубликатов в базе данных. Класс case, который я использую, выглядит примерно так:
case class Foo(someRelatedId: String, email: String ...)
Я хотел бы добавить естественный ключ, который состоит из электронной почты someRelatedId+, и 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 я сопоставляю пользовательский контекст salat:
implicit val ctx = new Context() {
val name = Some("Custom Context")
}
ctx.registerGlobalKeyOverride(remapThis = "naturalKey", toThisInstead = "_id")
Таким образом, я избегаю обязательного (бессмысленного) поля _id в моих классах домена, но мне приходится перегружать apply() для объекта-компаньона, что кажется немного неуклюжим.
1 ответ
Основной разработчик 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" или предоставить специальные переопределения @Key для каждого объекта.
Лично мне не нравится давать _id другое имя в ваших моделях, так как тогда ваши запросы Mongo должны использовать сериализованный ключ "_id", в то время как вся ваша бизнес-логика должна использовать имя поля класса case ("naturalKey" или что-то еще), но YMMV,
PS Наш список рассылки находится по адресу http://groups.google.com/group/scala-salat - я увижу ваш вопрос там быстрее, чем переполнение стека.