it-swarm.com.de

Verschachtelte Objekte in Mungo speichern

Ich komme aus einem PHP/MySQL-Hintergrund und habe Schwierigkeiten mit den besten Vorgehensweisen hinsichtlich der Strukturierung und Speicherung meiner Daten.

Ich versuche, eine kleine Anwendung zu erstellen, in der ich Rezepte mit mehreren Zutaten hinzufügen kann. Ich habe eine Menge vorgefüllter Zutaten als Samendaten, deren Schema folgendermaßen aussieht:

var IngredientSchema = new Schema({
    name: {
        type: String,
        trim: true,
        required: true,
        index: {
            unique: true
        }
    },
    created: {
        type: Date,
        default: Date.now
    }
});

var Ingredient = mongoose.model('Ingredient', IngredientSchema);

Ein Rezept sieht aktuell so aus:

var RecipeSchema = new Schema({
    name: {
      type: String,
      trim: true
    },
    ingredients: [
      {
        type: Schema.Types.ObjectId,
        ref: 'RecipeIngredient'
      }
    ],
    created: {
      type: Date,
      default: Date.now
    }
});

var Recipe = mongoose.model('Recipe', RecipeSchema);

Zum Schluss habe ich ein RezeptIngredientSchema. Hier könnte sich mein MySQL-Hintergrund einschleichen. Der Grund, warum ich es auf diese Weise gemacht habe, ist, dass ich die eine oder viele Beziehung zwischen Rezepten und Zutaten herstellen möchte, aber ich möchte auch eine Einheit angeben können:

var RecipeIngredientSchema = new Schema({
    recipe: {
      type: Schema.Types.ObjectId,
      ref: 'Recipe'
    },
    ingredient: {
      type: Schema.Types.ObjectId,
      ref: 'Ingredient'
    },
    unit: {
      type: Schema.Types.ObjectId,
      ref: 'Unit'
    },
    created: {
      type: Date,
      default: Date.now
    }
});

var RecipeIngredient = mongoose.model('RecipeIngredient', RecipeIngredientSchema);

Meine Frage besteht aus zwei Teilen:

  • Mache ich dies auf sinnvolle Weise in Bezug auf Datenmodellierung oder bin ich weit weg?
  • Wie würde der Prozess des Speicherns eines Rezepts mit mehreren Bestandteilen tatsächlich aussehen? 

Ich denke derzeit über Folgendes nach:

exports.create = function(req, res) {

  var recipe = new Recipe(req.body);

  recipe.save(function(err, recipe) {
    if (err) {
      return res.jsonp(err);
    } else {

      // Loop ingredients
      if (req.body.ingredients) {
        for(var prop in req.body.ingredients) {
          var recipeIngredient = new RecipeIngredient({
            recipeId: recipe._id,
            ingredientId: mongoose.Types.ObjectId(req.body.ingredients[prop])
          });

          recipeIngredient.save(function(err, recipeIngredient) {
            if (err) {
              return res.jsonp(err);
            } else {
              recipe.recipeIngredients.Push(recipeIngredient._id);
              recipe.save(function(err, recipe) {
                return res.jsonp(recipe);
              });
            }
          });
        };
      }
    }
  });
}

Ich finde, das ist kompliziert und im Allgemeinen falsch , ich würde mich also über eine Anleitung freuen!

14
James

Das Schöne an NoSQL-Datenbanken (oder Dokumentenspeichern im Allgemeinen) ist, dass Sie Ihre Daten nicht in mehrere Tabellen/Sammlungen aufteilen müssen. Sie können alle zugehörigen Daten in einer einzigen Entität speichern, sodass Ihre Leseoperationen auf einen Schlag erfolgen. 

Es gibt keinen "richtigen" Ansatz, um dies zu tun, aber wenn Sie NoSQL verwenden möchten, würde ich in Betracht ziehen, das gesamte Rezept (Rezept, Zutaten und Anweisungen) als ein einziges Dokument zu speichern, anstatt die Daten in 3 oder 4 Tabellen a-la aufzuteilen relationales Modell.

Ich würde zum Beispiel ein einzelnes Rezept wie folgt speichern:

recipe = {
    name: 'name of recipe'
    time: '45 minutes'
    ingredients : [
       {qty: 3, unit: 'item', name: 'tomatoes'},
       {qty: 0.5, unit: 'tbs', name: 'salt'},
       {qty: 1, name: 'item', name: 'avocado'} 
    ]
}

Nun, das ist kein Feenstaub. Es wird Zeiten geben, in denen die Aufteilung der Daten in mehrere Tabellen/Sammlungen und eine relationale Abfragesprache (wie SQL) für die Abfrage von Daten von Vorteil sind. Wenn Sie beispielsweise alle Rezepte abfragen möchten, die "Tomaten" verwenden, die eine relationale Datenbank mit einer Join-Tabelle für die Rezept-/Zutatenrelationen haben, wäre dies viel einfacher als mit dem NoSQL-Ansatz. 

Dies ist eine Entscheidung, die Sie an einem Punkt treffen müssen: Sind Sie besser mit NoSQL oder mit einem RBMS für Ihre Anwendung?

9
Hector Correa

Wenn Sie verschachtelte Objekte in der Datenbank speichern möchten, haben Sie zwei Möglichkeiten: als eingebettetes Schema oder mit ref. Wenn Sie sie mit ref speichern, wird das verschachtelte Schema in einer separaten Sammlung gespeichert.

Schauen Sie sich dieses Beispiel an mongo-many-to-many und diesen Abschnitt: save-refs

1
maxi-code