あなたは、あなたのReview
秒でそれを参照し、Topic
用に別のスキーマを作成し、重複を避けたい場合は、次の
var TopicSchema = new mongoose.Schema({
key: String,
title: String
});
var ReviewSchema = new mongoose.Schema({
key: String,
phone: String,
...
topic: {type: Schema.Types.ObjectId, ref: 'Topic'}
});
var Topic = mongoose.model('Topic', TopicSchema);
var Review = mongoose.model('Review', ReviewSchema);
ここから、使用Topic
をサブ文書として使用してReview
を挿入する場合はpopulate()
methodです。自分自身の文書にauthor
を格納しているという事実に基づいて、そこに同じパターンをたどることを検討することができます。
私はkey
の使用について不思議です。 MongoDBは、一義的な一種のキーであるトップレベルのドキュメントにユニークな_id
をデフォルトで作成します。それがkey
のあなたの意図なら、おそらくMongoDBがそれを処理させるべきです。
しかし、一日の終わりには、問題に対する「正しい」解決法はなく、トレードオフの比較のみです。 MongoDBのメリットは、簡単に「質問するものを保存する」機能です。Topic
は非常に小さいので、レビューを取得するたびにトピックが必要な場合は、重複する価値があります。 MongoDBはコレクション内のACIDではありません(他のNoSQLオプションでは話すことができません)。この方法では、すべての埋め込みトピックを一度に更新すると、ユーザーに短時間の不一致が生じる可能性があります。
// Get entire review in one go, including subdocuments!
Review.findOne({ "key": "myReview" }, (err, doc) => { /* do things */ });
// On bulk topic updates, not all topics change at once (not ACIDic)
Review.update(
{ topic.title: 'foo' },
{ topic.title: 'bar' },
{ multi: true },
(err, doc) => {/* callback */ }
);
あなたはSQLの背景から来ている場合は、上記のpopulate()
パラダイムは、はるかに快適になります。また、MongoDBはドキュメントごとにACIDicなので、トピックを一度更新すれば、それを参照する他のすべてのドキュメントで十分です。その背景には、Mongooseが少なくとも2つのクエリを作成する必要があります:Review
の場合は1回、次にTopic
の場合はもう一度クエリを実行します。私の経験で
// To replace refs with documents two queries behind the scenes
Review.findOne({ key: 'myReview' })
.populate('topic').exec((err, review) => { /* do things */ })
// But updating a single topic is ACIDic, since reviews only contain references
Topic.update({ key: 'foo' }, { title: 'sci-fi' }, (err, res) => {/* more stuff */ })
あなたが制限するためにあなたのクエリパイプラインを押し、すべてのコストで、応答時間を削減したいしている場合を除き、populate()
との別個のスキーマは、余分なクエリのトレードオフの価値があります。
ありがとうございます!この種のデータの複製が受け入れられることを確認することが重要でした。:-) – MarcoS
絶対に!参考になった場合は回答を受け入れてください。 – ggallo
より完全な答えを得るために数日待つだけです... :-) – MarcoS