MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

So fragen Sie ein relatives Element mit MongoDB ab

Alles daran ist ziemlich schrecklich, Sie können unmöglich auf etwas wie die "Namen" -Werte indexieren und Ihr "Pfad" zu jedem Attribut wird überall variieren. Das ist also wirklich schlecht für Abfragen.

Mir ist aufgefallen, dass Sie „verschachtelte“ Strukturen erwähnen, und Sie könnten dies immer noch mit einem ähnlichen Vorschlag und einigen zusätzlichen Tags berücksichtigen, aber ich möchte, dass Sie dieses Beispiel vom Typ „Telefonbuch“ in Betracht ziehen:

{
    "phones": [
        {
           "type": "Home",
           "name" : "Jeff",
           "phone" : "123-123-1234"
        },
        {
           "type": "Work",
           "name" : "Jeff",
           "phone" : "123-123-1234"
        },
    ]
}

Da es sich tatsächlich um Unterdokumente innerhalb eines Arrays handelt, teilen sich Felder wie "Name" immer denselben Pfad, sodass Sie diese nicht nur indizieren können (was der Leistung zugute kommt), sondern die Abfrage ist auch sehr einfach:

db.collection({ "phones.name": "Jeff" })

Das macht genau das, was Sie brauchen, indem Sie „Jeff“ in einem beliebigen „Name“-Eintrag finden. Wenn Sie eine Hierarchie benötigen, fügen Sie einige Felder in diesen Unterdokumenten hinzu, um die Eltern-Kind-Beziehung anzugeben, die Sie bei der Nachbearbeitung verwenden können. Oder sogar als materialisierter Pfad, der Ihre Abfragen unterstützen könnte.

Es ist wirklich der bessere Ansatz.

Wenn Sie diese Art von Struktur wirklich beibehalten müssen, dann tun Sie zumindest so etwas mit dem JavaScript, das bei der ersten Übereinstimmung in der Tiefe aussteigt:

db.collection.find(
  function () {
    var found = false;

    var finder = function( obj, field, value ) {
      if ( obj.hasOwnProperty(field) && obj[field] == value )
        found = true;

      if (found) return true;

      for( var n in obj ) {
        if ( Object.prototype.toString.call(obj[n]) === "[object Object]" ) {
          finder( obj[n], field, value );
          if (found) return true;
        }
      }

    };

    finder( this, "name", "Jeff" );
    return found;

  }
)

Das dortige Format ist eine Kurzschreibweise für $where Operator, was ziemlich schlechte Nachrichten für die Leistung ist, aber Ihre Struktur bietet nicht viel andere Wahlmöglichkeiten. Auf jeden Fall sollte die Funktion in jedem verschachtelten Dokument rekursiv sein, bis das "Feld" mit dem "Wert" gefunden wird.

Für alles im Produktionsmaßstab sollten Sie wirklich versuchen, die Struktur in etwas zu ändern, das schnell indiziert und abgerufen werden kann. Das erste Beispiel soll Ihnen einen Ausgangspunkt geben. Sich für Abfragen auf willkürliches JavaScript zu verlassen, wie es Ihre derzeitige Struktur erfordert, ist eine schlechte Nachricht.