2016-08-06 16 views
6

In meiner aktuellen Mongo DB passende, Ich habe eine einfache Teil Sammlung, mit einem Elternteil Kindern Beziehung, wie folgt aus:Mongoose: label in Array finden und zurück Dokumente

{"partcode": "Parent1","children": ["Child1","Child2","Child3"]} 

{"partcode": "Child1","label": ["label1"]} 
{"partcode": "Child2","label": ["label1"]} 
{"partcode": "Child3","label": ["label1"]} 

Um die Kinder zurück von a partcode, verwende ich die folgende Mungo Funktion:

PartSchema.static('getChildren', function(query, callback) { 
    var self = this, 
    self.findOne(query, {children: 1, _id: 0}) 
    .exec(function(err, doc) { 
     return (self.find({ 
     "partcode": { 
      "$in": doc.children 
     } 
     }, {_id: 0}, callback)); 
    }); 
}); 

Dies gibt die folgende Anordnung:

[{"partcode": "Child1","label": ["label1"]}, 
{"partcode": "Child2","label": ["label1"]}, 
{"partcode": "Child3","label": ["label1"]}] 

Ich möchte ein Label-System implementieren, wobei ich ein Label als Metakind angeben kann und den Code alle untergeordneten Elemente zurückgeben kann, die diesem Label entsprechen.

{"partcode": "Parent1","children": ["*label1"]} 

zurückkehren würde:

[{"partcode": "Child1","label": ["label1"]}, 
{"partcode": "Child2","label": ["label1"]}, 
{"partcode": "Child3","label": ["label1"]}] 

ich ein Etikett in die mit einem Sonderzeichen als Ausgangs Kinder Feld des Mutter Dokument angeben werden (zur Zeit, ich bin mit ‚*‘, aber glücklich zu ändern das zu etwas anderem, wenn es sein muss).

Pseudocode:

  1. finden Eltern
  2. Erhalten Eltern ‚s Kinder Array
  3. In Array, wenn Kind beginnt mit Label Charakter
    1. erhalten Array aller partcodes von Teilen, die mit in Kinder Array
  4. Rückkehr Kinder Array

Kinder, die nicht voran Label und

  • Ersatz partcodes für Etikett passen Ein Label-Zeichen sollte ebenfalls zurückgegeben werden.

  • +1

    Sie können reguläre Ausdrücke in der Anweisung $ in verwenden. Etwas in der Art von 'find ({label: {$ in: [/ label1 /]}}, Callback)' Stellen Sie sicher, dass Sie einen Index für das Feld 'label' hinzufügen – Andreas

    +0

    Danke dafür. Mir geht es gut mit den Details um einen Fund. Ich habe eine Label-Funktion erstellt, die alle Objekte mit einem bestimmten Label zurückgibt. Was ich nicht weiß, ist, wie man es am besten strukturiert; das heißt, die breiten Striche. Ich lehne mich einer Aggregate-Pipeline zu. – Terry

    Antwort

    1

    Ich habe dies wie folgt zu arbeiten:

    PartSchema.static('getChildren', function(query, callback) { 
        var self = this, 
        children = [], 
        labels = []; 
        self.findOne(query, {children: 1, _id: 0}) 
        .exec(function(err, doc) { 
         //find labels 
         labels = _.filter(doc.children, obj => /^\*/.test(obj)); 
         //remove labels from children array 
         children = _.difference(doc.children, labels); 
         //remove label identifier '*' 
         labels = _.map(labels, label => label.substring(1)); 
         self.find({ 
         vendor: vendor, 
         $or: [{ 
          "partcode": { 
          "$in": children 
          } 
         }, { 
          "label": { 
          "$in": labels 
          } 
         }] 
         }, {_id: 0}, callback); 
        }); 
    }); 
    

    ich in den Kommentaren interessiert wäre. Vor allem um Eleganz, Struktur, Konvention, etc. Alles so schlechte Form oder hässlich, macht es Ihr Auge ticken?

    +0

    brauchst du wirklich einen besonderen charakter, um zu unterscheiden? und wenden Sie Filter und Unterschied an und benutzen Sie Karte auch. Sie können es viel einfacher machen, indem Sie nur Sonderzeichen entfernen. –

    +0

    hat meine eigene Antwort als eine Verbesserung gepostet –

    0

    Anknüpfend mit OP's self answer,

    Sie nicht wirklich brauchen ein Sonderzeichen (*) hier ein Etikett von einem Kind Feld zu unterscheiden. Dies reduziert auch die Anzahl der verwendeten Array-Operationen (filter, difference, map).

    So nehme Sie keine Sonderzeichen für das Label haben, würde Ihre Sammlung wie folgt aussehen:

    {"partcode": "Parent1","children": ["label1"]} 
    

    und

    [{"partcode": "Child1","label": ["label1"]}, 
    {"partcode": "Child2","label": ["label1"]}, 
    {"partcode": "Child3","label": ["label1"]}] 
    

    So wird folgende Code geben Sie das gewünschte Ergebnis:

    Hinweis: Diese Lösung ist applicab le, wenn child Feld in einem doc ist kein label Feld in einem anderen doc und umgekehrt.

    +0

    Hi Naeem, danke für Ihre Antwort. Ich fürchte, wir brauchen ein spezielles Zeichen, um zwischen "Etiketten" und "Kindern" zu unterscheiden, da es die Möglichkeit gibt, dass Teilecodes den gleichen Namen wie Etiketten haben. – Terry