4

サブセットは興味深い、薄い MongoDB ラッパーのように見えます。

与えられた例の 1 つに、ツイートとユーザーがあります。ただし、UserサブドキュメントですTweet。従来の SQL では、これは Tweet から User への外部キーを持つ 2 つの別個のテーブルに正規化されます。MongoDB では、これは を必要とせずDBRef、ユーザーの保存ObjectIdで十分です。

Subset と Salat の両方で、これにより次のケース クラスが生成されます。

case class Tweet(_id: ObjectId, content: String, userId: ObjectId)
case class User(_id: ObjectId, name: String)

そのため、Tweet の ObjectId が実際に User に解決されるという保証はありません (型安全性が低くなります)。また、User を参照するクラスごとに同じクエリを作成する必要があります (または、それを何らかのトレイトに移動します)。

だから私が達成したいのはcase class Tweet(_id: ObjectId, content: String, userId: User)、 、コード内、およびObjectIdデータベース内にあることです。これは可能ですか?良い代替手段は何ですか?

4

2 に答える 2

0

アレクサンダー・アザロフの答えはおそらくうまくいきますが、個人的にはこのようにはしません。

あなたが持っているのは、ユーザーへの ObjectId 参照のみを持つツイートです。また、ツイートの読み込み中にユーザーを読み込みたいとします。これは、ドメインの操作がおそらく簡単であるためです。いずれにせよ、サブドキュメントを使用しない限り (常に良い選択であるとは限りません)、DB に再度クエリを実行してユーザー データを取得する必要があります。これは Alexander Azarov によって行われます。

ツイートを TweetWithUser などに変換する変換関数を使用することをお勧めします。

  def transform(tweet: Tweet) = TweetWithUser( tweet.id, tweet.content, findUserWithId(tweet.userId) ) 

1行のコードで非常に簡単に解決できることを、フレームワークが解決することを期待する理由がよくわかりません。

また、アプリケーションでは User オブジェクト全体が必要ない場合もあるため、常に必要であるとは限らないデータベースに対して 2 回クエリを実行するとコストがかかることを覚えておいてください。ユーザー データが本当に必要な場合にのみ、完全なユーザー データを含むケース クラスを使用する必要があります。

とにかく User オブジェクトを操作したい場合は、id 属性に直接アクセスできる User プロキシがあり、他のアクセスでは db クエリが実行されます。Java/SQL では、Hibernate はリレーションシップの遅延読み込みを行っていますが、MongoDB でそれを使用するのが良い考えであるかどうかはわかりませんし、不変性が壊れます

于 2013-01-01T20:43:04.970 に答える