ユーザーにとっては、現在のスキーマで問題ないと思います。複数の住所、電話番号、電子メール アドレスを配列に保持することは良いことです。なぜなら、特定の人物に対してそれらの数が多すぎてはならないからです。また、「この電子メール アドレスを持っている人」または「すべての電話番号を教えてください」を簡単に照会できます。この人"。あなたは冗長なe-mail
フィールドを持っているようですが、それはアカウントのアドレスのような特別な電子メールで、連絡先の電子メールとは区別されますか? もしそうなら、他のメンテナーのためにわかりやすい名前を付けaccount_email
ます。私は写真をブロブとして保持しませんが、それは他の要件であるとあなたは言ったので、私はそれを批判しません.
別の連絡先コレクションを使用してグループと連絡を取るというアイデアが気に入っています。contacts
各ドキュメントが 1 つの連絡先を表すコレクションを作成します。
{
"_id" : ObjectId("..."),
"owner_id" : ObjectId("..."), // reference to user document of contact owner
"contact_id" : ObjectId("..."), // reference to user document of contact
"group" : "Rivals" // group name
}
次のようなクエリをすばやく実行できます{ "owner_id" : 1, "contact_id" : 1 }
。{ "owner_id" : 1, "group" : 1 }
// get all contacts for user x
db.contacts.find({ "owner_id" : x })
// is user y a contact of user x?
db.contacts.count({ "owner_id" : x, "contact_id" : y }) != 0
// get all contacts in group "family" for user x
db.contacts.find({ "owner_id" : x, "group" : "family" })
連絡先を取得したら、わかりやすい表示情報を取得するために、2 番目のクエリ (アプリケーション レベルの結合) を実行して、連絡先の実際のユーザー ドキュメントを取得する必要があります。必要に応じて、連絡先情報の一部を連絡先ドキュメントに非正規化できます
{
"_id" : ObjectId("..."),
"owner_id" : ObjectId("..."), // reference to user document of contact owner
"contact_id" : ObjectId("..."), // reference to user document of contact
"group" : "Rivals", // group name
"contact_name" : "Franke Frankers"
}
一般的に必要な情報を含める場合は、2 番目のクエリを実行する必要はありませんが、連絡先が自分の情報を更新した場合は、それらを参照するすべての連絡先ドキュメントを更新する必要がある場合があります。