Este artículo proviene de un motor de traducción automática.

El programador políglota

Optar por NoSQL con MongoDB, Parte 3

Ted Neward

Descargar el código de ejemplo

Ted NewardÚltima vez, continúa la exploración de MongoDB a través del uso de las pruebas de exploración. I se describe cómo iniciar y detener el servidor durante una prueba, a continuación, mostramos cómo capturar referencias entre documentos y tratan algunas de las razones de la awkwardness de este modo. Ha llegado el tiempo para explorar algunas funciones MongoDB intermedias: las consultas de predicado, funciones de agregado y la compatibilidad con LINQ proporcionados por el ensamblado MongoDB.Linq. También le proporcionan algunas notas acerca de cómo alojar MongoDB en un entorno de producción.

Cuando se último nuestro Hero a la izquierda. . .

Por razones de espacio, no revisar la mayor parte de los artículos anteriores; en su lugar, se puede leer en línea en el de mayo de y problemas de junio en msdn.microsoft.com/magazine de . En el grupo de código asociado, sin embargo, las pruebas de exploración han sido desarrolla fuera para incluir un conjunto existente de ejemplo de datos para trabajar, con los caracteres de uno de los programas de TV favoritos. La figura 1, se muestra una prueba de exploración anterior, por medio del actualizador. Hasta ahora, todo perfecto.

Figura 1 de exploración de un ejemplo de la prueba

[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")));
        }

Al llamar a todas las personas anteriores. . .

En artículos anteriores, el código de cliente recuperado en todos los documentos que cumplen un criterio determinado (por ejemplo, que tiene un campo de “ lastname ” que coinciden con un determinado valor de tipo String o para un campo de “ _id ” que coinciden con un determinado Oid), pero que no he tratado cómo realizar consultas de tipo de predicado (como “ buscar todos los documentos donde el ‘ edad ’ campo tiene un valor superior a 18 ”). Según parece, MongoDB no utiliza una interfaz SQL para describir el que se ejecute la consulta; en su lugar, utiliza JavaScript/ECMAScript y en realidad puede aceptar bloques de código se ejecute en el servidor para el filtro o datos agregados, casi como un procedimiento almacenado.

Esto proporciona algunas capacidades como LINQ, incluso antes de examinar las capacidades LINQ que admite el ensamblado Mongo.Linq. Mediante la especificación de un documento que contiene un campo denominado “ $ donde ” y un bloque de código que describe el ejecución de código ECMAScript, se pueden crear arbitrariamente complejas de las consultas:

 

[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");
        }

Como puede observar, la llamada de búsqueda devuelve una instancia de ICursor, que, aunque sí mismo no es IEnumerable (es decir, no se puede utilizar en el bucle foreach), que contiene una propiedad de documentos es un IEnumerable <Document>. Si la consulta devolvería demasiado grande de un conjunto de datos, se puede limitar la ICursor para devolver los primeros resultados de nde estableciendo su propiedad limitar a n de .

La sintaxis del predicado de la consulta tiene cuatro modos diferentes, que se muestra en de figura 2.

La figura 2 de cuatro Syntaxes de predicado de consulta diferentes

[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));
        }

En los formularios de la segundo y terceros “ esto ” siempre hace referencia al objeto que se está examinando.

Puede enviar cualquier comando arbitrario (es decir, el código ECMAScript) a través del controlador a la base de datos, de hecho, el uso de documentos para transmitir el comando o consulta. Así, por ejemplo, el método Count suministrado por dicha interfaz IMongoCollection es simplemente una comodidad en este fragmento de código más detallado:

[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"]);
        }

Esto significa que cualquiera de las operaciones agregadas que se describe en la documentación de MongoDB, tales como “ distintos ” o “ grupo ”, por ejemplo, son accesible mediante el mecanismo de la mismo, aunque no es posible que se expone como métodos en las API de MongoDB.Driver.

Puede enviar comandos arbitrarios fuera de una consulta a la base de datos a través de la sintaxis de “ nombres especiales ” “ $ eval, ” que permite que todos los bloques de ECMAScript legítimo del código que se ejecute en el servidor, vuelva a esencialmente como un procedimiento almacenado:

[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"]);
        }

O bien, utilice la función Eval proporcionada en la base de datos directamente. Si no es lo suficientemente flexible, MongoDB permite el almacenamiento de las funciones de ECMAScript definido por el usuario en la instancia de la base de datos para la ejecución durante las consultas y bloques de ejecución en el servidor mediante la adición de funciones de ECMAScript a la colección de base de datos especial “ system.js ”, tal como se describe en el sitio Web de MongoDB .

La falta de LINQ

El controlador de C# MongoDB también tiene compatibilidad con LINQ, lo que permite a los desarrolladores escribir código de cliente MongoDB como, por ejemplo, lo que se muestra en de figura 3.

La figura 3 de un ejemplo de soporte técnico 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?");
        }

Y, de acuerdo con la naturaleza dinámica de la base de datos de MongoDB, este ejemplo requiere ninguna generación de código, simplemente la llamada a Linq para devolver un objeto que “ permite ” el proveedor de LINQ MongoDB. En el momento de redactar este artículo, el soporte LINQ es bastante rudimentario, pero es que se ha mejorado y por el tiempo de que impresión de alcance de este artículo, le resultará mucho mejor. Documentación de las nuevas características y los ejemplos se encontrará en la wiki del sitio del proyecto .

Gastos de envío es una función

Sobre todo en caso contrario, si MongoDB se va a utilizar en un entorno de producción, algunas cosas deben solucionarse para que sea menos complicado para los chaps deficientes que tienen que mantener los servidores de producción y servicios que se está ejecutando.

Para empezar, el proceso de servidor (mongod.exe) debe estar instalado como un servicio, que se ejecuta en una sesión de escritorio interactiva normalmente no se permite en un servidor de producción. Para ello, mongod.exe es compatible con una opción de instalación del servicio, “--instalar, ” que instala como un servicio que, a continuación, se puede iniciar el panel de servicios o la línea de comandos: “ net start MongoDB. ” Sin embargo, de escribir este artículo, hay una rareza pequeño del, comando de instalación, deduce la ruta de acceso al archivo ejecutable mediante la búsqueda en la línea de comandos utilizada para ejecutarlo, debe especificarse la ruta de acceso completa en la línea de comandos. Esto significa que si se instala MongoDB en C:\Prg\mongodb, deberá instalarlo como un servicio en un símbolo del sistema (con derechos administrativos) con el comando C:\Prg\mongodb\bin\mongod.exe--instalar.

Sin embargo, los parámetros de línea de comandos, como “--dbpath, ” debe aparecer también en ese comando de instalación, que significa que si la configuración de: el puerto, la ruta de acceso a los archivos de datos y así sucesivamente, cambiar, se debe volver a instalar el servicio. Afortunadamente, MongoDB es compatible con una opción de archivo de configuración proporcionada por el “--config ” opción de línea de comandos, por lo tanto, normalmente lo mejor es pasar la ruta de acceso del archivo de configuración completa para la instalación del servicio y realizar una configuración adicional desde allí:

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

Como es habitual, es la forma más sencilla de probar para asegurarse de que el servicio se está ejecutando correctamente para conectarse a él con el cliente mongo.exe que se incluye con la descarga de MongoDB. Y, dado que el servidor se comunica con los clientes a través de sockets, tiene que escribir los agujeros necesarios en el servidor de seguridad para permitir la comunicación entre servidores.

Éstos no son el Droids de datos que se busca

Por supuesto, no es probable que sea algo bueno, para proteger el servidor frente a los visitantes no deseados se convierta en una característica clave de acceso no seguro para el servidor MongoDB. MongoDB admite la autenticación, pero el sistema de seguridad en cualquier lugar no es casi tan sofisticada como la se ha encontrado con “ hierro grande ” bases de datos como, por ejemplo, SQL Server.

Normalmente, el primer paso es crear un inicio de sesión del Administrador de base de datos mediante la conexión a la base de datos con el cliente mongo.exe y agregar un usuario de administrador para la base de datos de administrador (una base de datos que contiene los datos para ejecutar y administrar todo el servidor MongoDB), por ejemplo:

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

Una vez hecho esto, cualquier acción adicional, incluso dentro de este tipo de shell, necesitará acceso autenticado, que se hace en el shell, autenticación explícita:

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

Ahora, el Administrador de base de datos puede agregar usuarios a una base de datos MongoDB por cambio de las bases de datos y el usuario utilizando la misma llamada addUser mostrada anteriormente:

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

Cuando se conecta a la base de datos a través de la Mongo.Driver, pasar la información de autenticación como parte de la cadena de conexión utilizada para crear el objeto Mongo y se producen de forma transparente la magia de autenticación mismo:

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

Naturalmente, las contraseñas no deberían estar codifica directamente en el código o almacenan abiertamente; utilizan la disciplina de la misma contraseña como befits cualquier aplicación basada en la base de datos. De hecho, toda la configuración (host, puerto, la contraseña y así sucesivamente) debe almacenarse en un archivo de configuración y recuperada a través de la clase ConfigurationManager.

Alcanzar fuera a tocar el código de algunas

Periódicamente, los administradores querrán consultar la instancia en ejecución para obtener información de diagnóstico sobre el servidor en ejecución. MongoDB admite una interfaz HTTP para interactuar con ella, que se ejecutan en un puerto de 1.000 numéricamente mayor que el puerto que está configurado para utilizar para la comunicación de cliente normales. Por lo tanto, como el puerto de MongoDB predeterminado es 27017, la interfaz HTTP puede encontrarse en el puerto 28017, tal como se muestra en de figura 4.

Figure 4 The HTTP Interface for Interacting with MongoDB

La figura 4 de La interfaz de HTTP para interactuar con MongoDB

Esta interfaz HTTP también permite que un método de comunicación más REST de estilo, que el controlador nativo de MongoDB.Driver y MongoDB.Linq; el sitio Web de MongoDB tiene detalles completos, pero básicamente la URL de HTTP para tener acceso al contenido de una colección se agregando el nombre de la base de datos y el nombre de la colección, separados por barras diagonales, como se muestra en de figura 5.

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

La figura 5 de la dirección URL de HTTP para tener acceso a contenido de una colección.

Para obtener más información acerca de cómo crear a un cliente REST con WCF, consulte el artículo MSDN “ REST en Windows Communication Foundation (WCF) ”.

Una palabra de Yoda

MongoDB es un producto rápidamente cambiantes y, a estos artículos, al explorar partes básicas de funcionalidad del MongoDB, dejan las áreas principales unexamined. Mientras MongoDB no es un sustituto directo de SQL Server, está demostrando para ser una alternativa viable de almacenamiento para las áreas donde los RDBMS tradicional no pasaje de avión tan bien. De forma similar, al igual que MongoDB es una evolución en curso, por lo tanto, es el proyecto de csharp-mongodb.  En el momento de redactar este artículo, muchas mejoras nuevas se dirigían en versión beta, incluidas las mejoras para trabajar con colecciones con establecimiento inflexible de tipos, objetos sin formato, así como mejora en gran medida el soporte técnico LINQ. Estar atento a ambos.

Mientras tanto, no obstante, es hora de onda de despedida a MongoDB y activar nuestra atención en otras partes del mundo de los desarrolladores que el programador de trabajo no puede estar familiarizado con (y posiblemente debe ser). Por ahora, no obstante, feliz codificación y recuerde, como la gran Yoda DevGuy master después de esto, “ A DevGuy usa el origen para el conocimiento y defensa; nunca para un ataque. ”

Ted Neward es un principal con Neward & Associates, una empresa independiente especializado en Microsoft .NET Framework y Java plataforma empresarial sistemas. Ha escrito más de 100 artículos, que es un experto en C#, los altavoces INETA y el autor y coautor de libros de una docena, incluido “ Professional F # 2.0 ” (Wrox, 2010). Consulta y mentors con regularidad. Ponerse en ted@tedneward.com de y lee su blog en blogs.tedneward.comde .

Thanks to the following technical experts for reviewing this article: Sam Corder and Craig Wilson