Wenn Sie Doppelarbeit vermeiden möchten, ein separates Schema für eine Topic
erstellen, es dann in Ihrem Review
s Referenz:
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);
Von hier Verwendung die populate()
method für, wenn Sie eine Review
mit einer als Filialdokument einfügen möchten. Basierend auf der Tatsache, dass Sie author
in einem eigenen Dokument speichern, können Sie das gleiche Muster in Betracht ziehen.
Ich bin neugierig auf Ihre Verwendung von key
. MongoDB erstellt standardmäßig einen eindeutigen _id
auf Top-Level-Dokumenten, eine Art Primärschlüssel. Wenn das Ihre Absicht für key
war, sollten Sie wahrscheinlich MongoDB damit umgehen lassen.
Aber am Ende des Tages gibt es keine "richtige" Lösung für Ihr Problem, nur ein Vergleich der Kompromisse. Ein Vorteil von MongoDB ist die Fähigkeit, "das, wonach Sie suchen" mit Leichtigkeit zu speichern, und da Topic
s ziemlich klein sind, lohnt sich die Duplizierung, wenn Sie bei jedem Abrufen von Themen Themen wünschen. MongoDB ist keine ACID innerhalb einer Sammlung (ich kann nicht für andere NoSQL-Optionen sprechen). Bei dieser Methode kann das gleichzeitige Aktualisieren aller eingebetteten Zweige zu kurzen Diskrepanzen für die Benutzer führen.
// 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 */ }
);
Wenn Sie aus einem SQL-Hintergrund kommen, das populate()
Paradigma oben beschrieben wird viel wohler fühlen. Und da MongoDB ACIDic pro Dokument ist, reicht das einmalige Aktualisieren eines Themas für alle anderen Dokumente aus, die darauf verweisen. Hinter den Kulissen erfordert dies, dass Mongoose mindestens zwei Abfragen durchführt: einmal für die Review
, dann erneut für die referenzierte .
// 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 */ })
Nach meiner Erfahrung, es sei denn, Sie Ihre Abfrage-Pipeline an die Grenze schieben und wollen Reaktionszeiten auf allen Kosten zu senken, getrennte Schemata mit populate()
ist der Kompromiss von zusätzlichen Abfragen wert.
Danke! Es war wichtig für mich, dass Duplikate dieser Art von Daten akzeptabel waren ... :-) – MarcoS
Absolut! Bitte akzeptieren Sie die Antwort, wenn es hilfreich war. – ggallo
Warte nur ein paar Tage mehr für eine vollständigere Antwort ... :-) – MarcoS