いくつかの提案。
実行するすべてのクエリと、保存する必要があるすべての種類のデータを把握します。たとえば、将来アクティビティを追加する予定はありますか、それともビーチとショップだけですか?
書き込みと読み取りの数を検討し、どちらを高速にする必要があるかを検討してください。
スキーマが長期的にスケーラブルであることを確認するために、時間の経過とともにドキュメントがどのように成長するかを判断します。
これら 2 つのアクティビティしかない場合は、次の 1 つのアプローチが考えられます。ユーザーごとに 1 日 1 つのレコード。
{ user: "user1",
date: "2012-12-01",
shopped: 0,
beached: 1
}
これで、アクティビティが 2 つであろうと 10 個であろうと、クエリがさらに簡単になります。
新しいアクティビティが発生すると、それに基づいて常に正しいレコードを更新する必要があります。ユーザー、日付、アクティビティを示すレコードをコレクションに追加するだけでよいと考えていた場合、挿入ははるかに高速ですが、クエリはユーザー、日付、およびアクティビティの両方をクエリする多くの作業を行う必要があります。
提案されたスキーマを使用した挿入/更新ステートメントは次のとおりです。
db.coll.update({"user":"username", "date": "somedate"}, {"shopped":{$inc:1}}, true)
それが言っていることは次のとおりです。「somedateのユーザー名について、shopped属性を1増やし、それが存在しない場合は作成します。別名「アップサート」(これが最後の「真の」引数です)。
これは、特定の日に activity1 を 2 回以上実行したが、activity2 をまったく実行しなかったすべてのユーザーに対するクエリです。
db.coll.find({"date":"somedate","shopped":0,"danced":{$gt:1}})
1 つのドキュメントが継続的かつ無制限に増加する可能性があるスキーマの選択には注意してください。
たとえば、日付とアクティビティの配列が増え続けるユーザー コレクションにすべてを格納すると、この問題が発生します。この説明については、ここで強調表示されているセクションを参照してください。また、大きなドキュメントが作業データ セットに取り込まれ続けることに注意してください。ドキュメントが巨大で、役に立たない (古い) データがたくさん含まれていると、ドキュメントのパフォーマンスが低下します。アプリケーション、およびディスク上のデータの断片化。
すべてのデータを 1 つのコレクションに入れる必要はありません。そのユーザーの属性の固定セットを持つユーザー コレクションを用意して、ユーザーの友人の数やその他の準安定情報を追跡し、ユーザーごとに毎日レコードを追加する user_activity コレクションを用意するのが最善の場合があります。彼らが行った活動。データの量または正規化または非正規化は、実行するクエリの種類と非常に密接に関連しています。