2016-04-04 12 views
0

Ich habe eine Sammlung für einige Bewertungen entworfen.
Das Review-Auflistungsschema enthält sowohl Beiträge als auch Themen.
Posts Eigenschaften (Schlüssel, Telefon, Datum, Inhalt, Autor.Name) sind direkte Kinder der Rezensionssammlung.
Themeneigenschaften (Schlüssel, Titel) sind untergeordnete Objekte des Themenobjekts, das ein untergeordnetes Objekt der Überprüfungssammlung ist.
Jeder Beitrag gehört zu einem Thema.
Jeder Post-Schlüssel ist einzigartig, jeder Thema-Schlüssel ist einzigartig.
Wenn viele Beiträge zu einem Thema gehören, ist Thema Daten für jede Überprüfung wiederholt (NoSQL ist nicht ACID, rechts :-)Mungo: Wie vermeidet man das Duplizieren von Dokumenten?

Die Frage ist: die Entscheidung Thema Eigenschaften richtig zu duplizieren ist, oder sollte ich anders verwenden Sammlungen für Beiträge und Themen?

Das ist mein Modell ist:

var reviewSchema = new mongoose.Schema({ 
    key: String, 
    phone: String, 
    date: Date, 
    contents: String, 
    author: { 
    name: String, 
    }, 
    topic: { 
    key: String, 
    title: String, 
    }, 
}); 
reviewSchema.index({ 'key': 1 }, { unique: true }); 
reviewSchema.index({ 'phone': 1 }, { unique: false }); 
reviewSchema.index({ 'topic.key': 1 }, { unique: false }); 

Antwort

4

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.

+0

Danke! Es war wichtig für mich, dass Duplikate dieser Art von Daten akzeptabel waren ... :-) – MarcoS

+0

Absolut! Bitte akzeptieren Sie die Antwort, wenn es hilfreich war. – ggallo

+0

Warte nur ein paar Tage mehr für eine vollständigere Antwort ... :-) – MarcoS

Verwandte Themen