Dieser Artikel wurde maschinell übersetzt.

Der Programmierer bei der Arbeit

In Richtung NoSQL mit MongoDB, Teil 3

Ted Neward

Beispielcode herunterladen

Ted NewardIm letzten Fortsetzung ich meine Untersuchung von MongoDB über die Verwendung der Untersuchung Tests. Ich zum Starten und Beenden des Servers während eines Tests beschrieben und gezeigt, wie Cross Dokumentreferenzen erfassen und erläutert einige der die Logik hinter der Awkwardness damit. Jetzt ist es an der Zeit, um einige weitere intermediate MongoDB Funktionen zu entdecken: Abfragen, die Aggregatfunktionen und der LINQ-Unterstützung durch die Assembly MongoDB.Linq-Prädikat. Ich werde auch einige Hinweise zu hosten MongoDB in einer Produktionsumgebung bereitstellen.

Aus Gründen des Speicherplatzes wird nicht ich viel von der vorherigen Beiträge überprüfen; stattdessen lesen Sie Sie online in der kannJuni Probleme msdn.microsoft.com/magazine-. In diesem Bündel zugeordneten Code haben jedoch die Untersuchung Tests aus aufgezeichnet wurde auf einen bereits vorhandenen Beispiels von Daten zu verwenden mit Zeichen aus einem meiner Lieblingsfernsehsendungen enthalten. Abbildung 1 zeigt vorherige Untersuchung Test mithilfe des Aktualisierungsprogramms. So weit, so gut.

Abbildung 1 ein Beispiel Exploration Test

[TestMethod]
        public void StoreAndCountFamilyWithOid()
        {
          var oidGen = new OidGenerator();
          var peter = new Document();
          peter["firstname"] = "Peter";
          peter["lastname"] = "Griffin";
          peter["_id"] = oidGen.Generate();

          var lois = new Document();
          lois["firstname"] = "Lois";
          lois["lastname"] = "Griffin";
          lois["_id"] = oidGen.Generate();

          peter["spouse"] = lois["_id"];
          lois["spouse"] = peter["_id"];

          var cast = new[] { peter, lois };
          var fg = db["exploretests"]["familyguy"];
          fg.Insert(cast);

          Assert.AreEqual(peter["spouse"], lois["_id"]);
          Assert.AreEqual(
            fg.FindOne(new Document().Append("_id",
              peter["spouse"])).ToString(), lois.ToString());

          Assert.AreEqual(2,
            fg.Count(new Document().Append("lastname", "Griffin")));
        }

Alle alte Personen wird aufgerufen. . .

In früheren Artikeln der Clientcode entweder alle Dokumente, die einer bestimmten Kriterien (z. B. mit einem “ Nachname ” Feldes entsprechen bestimmten String oder ein “ _id ”-Feld entspricht einer bestimmten Oid) abgerufen wurde, jedoch noch nicht erwähnt wie Prädikat-artige Abfragen (z. B. “ alle Dokumente zu suchen, in denen die ‘ ALTER ’ Feld hat einen höheren Wert als 18 ”). Wie sich herausstellt, MongoDB keine SQL-Oberfläche verwenden, um die auszuführende Abfrage zu beschreiben; stattdessen ECMAScript/JavaScript verwendet, und in der Tat annehmen Codeblöcke, die auf dem Server filtern oder die aggregierten Daten fast wie eine gespeicherte Prozedur ausführen kann.

Dies bietet einige LINQ-ähnliche Funktionen vor der Betrachtung der LINQ-Funktionen, die von der Assembly Mongo.Linq unterstützt. Durch Angabe eines Dokuments mit eine Feld mit der Bezeichnung “ $, wobei ” und Beschreiben des ECMAScript-Codes zur Ausführung eines Codeblocks willkürlich komplexe Abfragen können erstellt werden:

 

[TestMethod]
        public void Where()
        {
          ICursor oldFolks =
            db["exploretests"]["familyguy"].Find(
            new Document().Append("$where", 
            new Code("this.gender === 'F'")));
          bool found = false;
          foreach (var d in oldFolks.Documents)
            found = true;
          Assert.IsTrue(found, "Found people");
        }

Wie Sie sehen können, gibt der Aufruf suchen eine ICursor-Instanz, die zwar selbst nicht IEnumerable (d. h. nicht in der Foreach-Schleife verwendet werden kann) ist, enthält die Documents-Eigenschaft, die ein IEnumerable <Document> zurück. Wenn die Abfrage zu großen, einen Satz von Daten zurückgeben würde, kann die ICursor begrenzt werden, um den ersten n Ergebnissen durch Setzen der Limit-Eigenschaft auf n-.

Die Abfragesyntax Prädikat wird in vier verschiedenen Varianten, dargestellt in Abbildung 2 .

Abbildung 2 vier unterschiedlichen Syntaxformen für Query-Prädikats

[TestMethod]
        public void PredicateQuery()
        {
          ICursor oldFolks =
            db["exploretests"]["familyguy"].Find(
            new Document().Append("age",
            new Document().Append("$gt", 18)));
          Assert.AreEqual(6, CountDocuments(oldFolks));

          oldFolks =
            db["exploretests"]["familyguy"].Find(
            new Document().Append("$where",
            new Code("this.age > 18")));
          Assert.AreEqual(6, CountDocuments(oldFolks));

          oldFolks =
            db["exploretests"]["familyguy"].Find("this.age > 18");
          Assert.AreEqual(6, CountDocuments(oldFolks));

          oldFolks =
            db["exploretests"]["familyguy"].Find(
            new Document().Append("$where",
            new Code("function(x) { return this.age > 18; }")));
          Assert.AreEqual(6, CountDocuments(oldFolks));
        }

In der zweiten und dritten Formulare verweist “ dies ” immer auf das Objekt überprüft wird.

Sie können jeden beliebigen Befehl (d. h. ECMAScript-Code) über den Treiber in der Datenbank tatsächlich senden mithilfe von Dokumenten um zu übermitteln, die Abfrage oder den Befehl. Beispielsweise ist die Count-Methode über die Schnittstelle IMongoCollection bereitgestellte also eigentlich nur eine benutzerfreundliche um dieser Ausschnitt ausführlicher:

[TestMethod]
        public void CountGriffins()
        {
          var resultDoc = db["exploretests"].SendCommand(
            new Document()
              .Append("count", "familyguy")
              .Append("query",
                new Document().Append("lastname", "Griffin"))
            );
          Assert.AreEqual(6, (double)resultDoc["n"]);
        }

Dies bedeutet, dass die aggregierte Vorgänge beschrieben, die durch die Dokumentation MongoDB z. B. “ unterschiedliche ” oder “ Gruppe ” beispielsweise über denselben Mechanismus, obwohl Sie nicht als Methoden auf die APIs MongoDB.Driver angezeigt werden können.

Sie können willkürliche Befehle außerhalb der eine Abfrage an die Datenbank über die Syntax der “ spezielle Namen ” “ $, eval ” ermöglicht legitimen ECMAScript Codeblock erneut im Wesentlichen als eine gespeicherte Prozedur auf dem Server ausgeführt werden soll, senden:

[TestMethod]
        public void UseDatabaseAsCalculator()
        {
          var resultDoc = db["exploretests"].SendCommand(
            new Document()
              .Append("$eval", 
                new CodeWScope { 
                  Value = "function() { return 3 + 3; }", 
                  Scope = new Document() }));
          TestContext.WriteLine("eval returned {0}", resultDoc.ToString());
          Assert.AreEqual(6, (double)resultDoc["retval"]);
        }

Oder verwenden Sie die bereitgestellte Eval-Funktion direkt in der Datenbank. Wenn, nicht flexibel genug ist, lässt MongoDB wie beschrieben, die auf der Website von MongoDB die Speicherung von benutzerdefinierten ECMAScript-Funktionen in der Datenbankinstanz für die Ausführung beim Abfragen und serverseitige Ausführung blockiert die spezielle Datenbank-Auflistung “ system.js, ” ECMAScript-Funktionen hinzufügen.

Fehlende LINQ

Der C#-MongoDB Treiber verfügt auch über LINQ-Unterstützung, so dass Entwickler schreiben MongoDB Clientcode wie was in Abbildung 3 angezeigt werden.

Abbildung 3 ein Beispiel für die Unterstützung von LINQ

[TestMethod]
        public void LINQQuery()
        {
          var fg = db["exploretests"]["familyguy"];
          var results = 
            from d in fg.Linq() 
            where ((string)d["lastname"]) == "Brown" 
            select d;
          bool found = false;
          foreach (var d in results)
          {
            found = true;
            TestContext.WriteLine("Found {0}", d);
          }
          Assert.IsTrue(found, "No Browns found?");
        }

Und dieses Beispiel ist im Einklang mit der dynamischen Natur der Datenbank MongoDB, keine Codegenerierung, nur den Aufruf von Linq, die sich um ein Objekt zurückzugeben, das “ MongoDB LINQ-Anbieter ermöglicht ” erforderlich. Zum Zeitpunkt Erstellung dieses Dokuments LINQ-Unterstützung ist ziemlich elementare aber wird verbessert wird und durch die Zeit, die in diesem Artikel drucken erreicht, werden deutlich verbessert. Dokumentation zu den neuen Funktionen und Beispiele werden in der Wiki der Projektwebsite-von .

Versand ist ein Feature

Über allen anderen Wenn MongoDB in einer Produktionsumgebung verwendet werden soll, müssen ein paar Dinge weniger mühsam für schlechte Chaps erleichtern, die den Produktionsservern und ausgeführten Dienste bleiben behoben werden.

Um zu Beginn des Serverprozesses (mongod.exe) als Dienst installiert werden muss – Ausführung in einer interaktiven desktop-Sitzung in der Regel darf nicht auf einem Produktionsserver. Zu diesem Zweck mongod.exe unterstützt eine Installationsoption für den Dienst “--installieren, ”, installiert er als ein Dienst, der anschließend durch im Bereich Services oder der Befehlszeile aus gestartet werden kann: “ net Start MongoDB. ” Allerdings als der Erstellung dieses Dokuments ist eine kleine Besonderheit im--Installation Befehl – es leitet den Pfad zu der ausführbaren Datei ab, anhand der in der Befehlszeile verwendet, so, dass der vollständige Pfad muss, in der Befehlszeile angegeben werden ausführen. Dies bedeutet, dass wenn MongoDB in C:\Prg\mongodb installiert ist, Sie es installieren müssen als einen Dienst an einer Eingabeaufforderung (mit Administratorrechten) mit dem Befehl C:\Prg\mongodb\bin\mongod.exe--zu installieren.

Allerdings alle Befehlszeilenparameter z. B. “--Dbpath, ” muss auch angezeigt werden, dass Installationsbefehl, d., h. wenn die Einstellungen – port, Pfad, den Datendateien usw. – ändern, der Dienst muss neu installiert werden. Glücklicherweise MongoDB eine Datei Konfigurationsoption vom unterstützt die “--Config ” Befehlszeilenoption, also in der Regel der beste Ansatz ist übergeben den vollständigen Config-Dateipfad zu den Dienst installieren, und führen Sie alle zusätzlichen Konfiguration von dort aus:

C:\Prg\mongodb\bin\mongod.exe --config C:\Prg\mongodb\bin\mongo.cfg --install
net start MongoDB

Ist wie gewohnt die einfachste Methode zum Testen, um sicherzustellen, dass der Dienst erfolgreich ausgeführt wird, mit dem mongo.exe-Client herstellen, der mit dem MongoDB-Download enthalten ist. Und da der Server mit den Clients über Sockets kommuniziert, müssen Sie die erforderlichen Löcher in Firewalls, um die Kommunikation zwischen Servern zulassen herumzustöbern.

Dabei werden die Daten Droids, die Sie für die Suche sind nicht

Natürlich keine ungesicherten Zugriff auf den Server MongoDB wahrscheinlich eine gute Sache, damit Absicherung des Servers gegen unerwünschte Besucher ein wichtiges Feature zu. MongoDB unterstützt die Authentifizierung, aber das Sicherheitssystem ist nicht überall near als anspruchsvolle, mit “ big Bügeleisen ” Datenbanken wie SQL Server gefunden.

I. d. r. der erste Schritt ist die Erstellung eines Datenbank-Benutzername Admin durch Herstellen einer Verbindung mit der Datenbank mit dem Client mongo.exe und der Verwaltungsdatenbank (eine Datenbank mit Daten, die für das Ausführen und Verwalten des gesamten MongoDB-Servers), einen Admin-Benutzer hinzugefügt werden wie folgt:

> use admin
> db.addUser("dba", "dbapassword")

Sobald dies geschehen ist, sind keine weiteren Aktionen, sogar innerhalb dieser Shell authentifizierten Zugriff erforderlich, die in der Shell von expliziten Authentifizierung ausgeführt wird:

> db.authenticate("dba", "dbapassword")

Der DBA kann Benutzer nun auf eine Datenbank MongoDB hinzufügen, durch Ändern von Datenbanken und Hinzufügen des Benutzers mithilfe des gleichen AddUser-Aufrufs weiter oben gezeigt:

> use mydatabase
> db.addUser("billg", "password")

Bei der Verbindung mit der Datenbank über die Mongo.Driver die Authentifizierungsinformationen als Teil der zum Erstellen des Objekts Mongo verwendete Verbindungszeichenfolge übergeben, und die gleichen Authentifizierung magische geschieht transparent:

var mongo = new Mongo("Username=billg;Password=password");

Natürlich Kennwörter sollte nicht direkt in den Code hartcodiert sein oder offene gespeichert; verwenden Sie dasselbe Kennwort-Disziplin wie jeder Anwendung die Datenbank gesichert befits haben. Tatsächlich sollte die gesamte Konfiguration (Host, Anschluss, Kennwort usw.) in einer Konfigurationsdatei gespeichert und über die ConfigurationManager-Klasse abgerufen werden.

Zu einigen Code Touch erreicht

Administratoren sollten in regelmäßigen Abständen Betrachten der ausgeführten Instanz Diagnoseinformationen über die ausgeführten Server erhalten. MongoDB unterstützt HTTP-Schnittstelle für die Interaktion mit, auf einen Port numerisch 1.000, die höher sind als Port konfiguriert ist für die normale Kommunikation verwenden. Auf diese Weise ist der Standardport für MongoDB 27017 sich HTTP-Schnittstelle auf Port 28017, befinden wie in Abbildung 4 .

Figure 4 The HTTP Interface for Interacting with MongoDB

Abbildung 4 Die HTTP-Schnittstelle für die Interaktion mit MongoDB

Diese HTTP-Schnittstelle ermöglicht einen weitere REST-artigen Kommunikation Ansatz im Gegensatz zu den systemeigenen Treiber in MongoDB.Driver und MongoDB.Linq; die MongoDB-Website verfügt über alle Details jedoch im Wesentlichen die HTTP-URL für den Zugriff auf eine Auflistung von Inhalt wird angegeben, indem Sie den Datenbanknamen und den Namen der Auflistung, getrennt durch Schrägstriche, als in Abbildung 5 .

Figure 5 The HTTP URL for Accessing a Collection’s Contents

Abbildung 5 die HTTP-URL für den Zugriff auf die Inhalte einer Auflistung

Weitere Informationen über das Erstellen eines REST-Clients mithilfe von WCF finden Sie im MSDN-Artikel “ REST in Windows Communication Foundation (WCF) ”.

Ein Wort aus Yoda

MongoDB ist ein sich schnell entwickelnde Produkt und diese Artikel beim Erforschen zentrale Teile des MongoDB-Funktionalität ohne unexamined Hauptbereiche. Während MongoDB direkten Ersatz für SQL Server nicht, ist es zum Nachweis zu eine Speicherung geeignete Alternative für Bereiche, in denen die herkömmlichen RDBMS gut fare nicht. Ebenso wie MongoDB eine Weiterentwicklung in Bearbeitung ist, ist also Mongodb Csharp-Projekt.  Zum Zeitpunkt Erstellung dieses Dokuments viele neue Verbesserungen wurden ausführlich Beta, einschließlich der Verbesserungen bei der Arbeit mit stark typisierten Auflistungen mithilfe von einfache Objekten als auch erheblich verbesserte Unterstützung für LINQ. Kontrollieren Sie auf beide.

Allerdings ist es in der Zwischenzeit Zeit zu wave-Farewell um MongoDB, und schalten Sie unsere Aufmerksamkeit zu anderen Teilen der Welt der Entwickler, der nicht der Programmierer arbeiten möglicherweise mit vertraut sein (und wohl werden sollte). Im Moment jedoch viel Spaß beim Codieren, und beachten Sie, dass als großartige DevGuy Master-Yoda einmal gesagt “ ein DevGuy verwendet die Quelle für Kenntnisse und Verteidigung; nie für eine Hack. ”

Ted Neward ist ein Principal mit Neward & Associates, eine unabhängige fest, die auf in Unternehmen Microsoft .NET Framework und der Java-Plattform Systeme. Er hat mehr als 100 Artikeln geschrieben ist C#-MVP, INETA-Sprecher und Autor und Mitautor von einem Dutzend Bücher, einschließlich “ Professional f# 2.0 ” (Wrox 2010). Er konsultiert und regelmäßig mentors. Sie erreichen ihn unter ted@tedneward.com -, und Lesen Sie seinen Blog unter blogs.tedneward.com-.

Unser Dank gilt den folgenden technischen Experten für das Lektorat dieses Artikels: Sam Corder and Craig Wilson