What is the best way to handle compsite keys when using Salat with MongoDB?

I am using Salat with MongoDB and I am trying to convert to natural keys to avoid duplication in the database. The case class that I use looks something like this:

case class Foo(someRelatedId: String, email: String ...) 

I would like to add a natural key that consists of some RelatedId + email address and use MongoDB instead of the default ObjectId. From the documentation, I get the feeling that this is possible, but I'm still groping for a working solution. This is largely due to the fact that I'm not sure of myself with Scala, I'm sure.

Update: I now have a working solution, but I'm still wondering if this is the best way.

 case class Foo(someRelatedId: String, email: String, naturalKey: String) object Foo { def apply((someRelatedId: String, email: String) { apply(someRelatedId, email, someRelatedId+email) } } 

And then in package.scala I map the custom salad context :

 implicit val ctx = new Context() { val name = Some("Custom Context") } ctx.registerGlobalKeyOverride(remapThis = "naturalKey", toThisInstead = "_id") 

This way, I avoid having a required (meaningless) _id field in my domain classes, but I need to overload apply () in the companion object, which seems a bit awkward.

+6
source share
1 answer

chief developer of Salat.

As Milan suggested, create a case class for your composite key:

 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 */ ) 

If you object to "_id" as the field name, you can use global redefinition in context to reassign "_id" to "naturalKey" or set ad hoc @Key overrides for each object.

I personally don't like giving _id a different name in your models, since your Mongo requests should use the serialized key "_id", while all your business logic should use the name of the case class field ("naturalKey" or something else) but ymmv.

PS Our mailing list is at http://groups.google.com/group/scala-salat - I will see your question faster than Stack Overflow.

+5
source

Source: https://habr.com/ru/post/906128/


All Articles