Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
945 views
in Technique[技术] by (71.8m points)

scala - How to model an entity with many children in Sorm?

I have a Workspace and Document entities, with the idea that a workspace can contain zero, one, or more documents. My first approach to model this was:

case class Workspace(name: String, documents: Seq[Document])

but this will not scale well since my workspaces may contain many documents. Fortunately, my business requirement allow me to treat workspaces and documents separately (in the sense that when I have a workspace, there is no reason or invariant that forces me to consider all documents contained in it).

Question: I am wondering: how would I model Workspace and Document in Sorm so that I have a link between the two but do not have to load all documents of a workspace? I imagine to have a Repository that would give me access to the documents of a workspace, with pagination support.)

case class Workspace(name: String)
case class Document(name: String, /* ... */)

trait WorkspaceRepository {
  def children(ws: Workspace, offset: Long, limit: Long)
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Easy peasy! You define them unrelated:

case class Workspace ( name : String )
case class Document ( ... )

Then you choose a way you wish them to be linked. I see two.

Variant #1

case class WorkspaceDocuments 
  ( workspace : Workspace, documents : Seq[Document] )

And get all documents of a workspace like so:

Db.query[WorkspaceDocuments]
  .whereEqual("workspace", theWorkspace)
  .fetchOne()
  .map(_.documents)
  .getOrElse(Seq())

In this case it makes sense to specify the workspace property as unique in instance declaration:

... Instance (
  entities = Set() +
             Entity[WorkspaceDocuments]( unique = Set() + Seq("workspace") )
  ...
)

Variant #2

case class WorkspaceToDocument
  ( workspace : Workspace, document : Document )

And get documents of a workspace like so:

Db.query[WorkspaceToDocument]
  .whereEqual("workspace", theWorkspace)
  .whereEqual("document.name", "...") // ability to filter docs
  .fetch()
  .map(_.document)

First variant won't let you filter docs in your query (at least in SORM v0.3.*) but due to ability to set a unique constraint on a workspace it should perform better on workspace-based queries. The second variant is more flexible, allowing you to apply all kinds of filters.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...