<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Códice | Entradas sobre «mongodb»</title><description>Feed RSS de publicaciones etiquetadas con mongodb</description><link>https://javguerra.github.io/</link><item><title>Conexión persistente a MongoDB en Node.js</title><link>https://javguerra.github.io/blog/mongodb-connect</link><guid isPermaLink="true">https://javguerra.github.io/blog/mongodb-connect</guid><description>Abrir una única conexión a la base de datos a través de los distintos módulos de la aplicación</description><pubDate>Sun, 24 Jul 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/mongodb.B38n9K_s_1aeGYn.webp&quot; alt=&quot;MongoDB&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#node.js&lt;/em&gt;, &lt;em&gt;#express&lt;/em&gt;, &lt;em&gt;#mongodb&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Esta semana tocó aprender sobre &lt;strong&gt;MongoDB&lt;/strong&gt;. Una de las cuestiones que me llamaron la atención en los ejercicios que realizamos era la necesidad de abrir y cerrar la conexión a la Base de Datos (en adelante «BBDD») en cada consulta, algo que supone una sobrecarga importante para el servidor, así que me puse a investigar la manera de hacer que la conexión a la BBDD permaneciese abierta y dando servicio a través de los distintos módulos de la aplicación. Esto es lo que descubrí, con ayuda de la comunidad.&lt;/p&gt;
&lt;h2 id=&quot;cambiando-el-chip&quot;&gt;Cambiando el chip&lt;/h2&gt;
&lt;p&gt;Pasar de manejar datos embebidos en módulos como en el caso de la publicación sobre &lt;a href=&quot;/blog/filtrado-multiple&quot;&gt;filtrado múltiple&lt;/a&gt; a consultar una base de datos como &lt;strong&gt;MongoDB&lt;/strong&gt; presenta retos importantes. el principal es que debo establecer la conexión al servicio y esperar una respuesta. Una consulta típica a MongoDB tendría esta forma:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;NODE_ENV&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;production&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;dotenv&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;config&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; mongoClient&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;mongodb&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).MongoClient;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; url&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;process&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_HOST&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}:${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;process&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_PORT&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}/`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; db_name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_DATABASE&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; collection&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;products&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(url, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;database&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (err) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;throw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; err;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; db&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; database.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;db&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(db_name);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    db.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;collection&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(collection).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;find&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;toArray&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;result&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (err) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;throw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; err;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(result);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        database.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;close&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;En la primera línea, en función de si la aplicación está funcionando en local, en modo desarrollo, o bien en producción en el servidor, cargo o no el módulo &lt;code&gt;dotenv&lt;/code&gt; que me permite tener las variables globales que luego usaré en url y db_name por ejemplo definidas en un fichero &lt;code&gt;.env&lt;/code&gt;. Puedes ampliar conocimientos sobre este asunto en &lt;a href=&quot;https://www.npmjs.com/package/dotenv&quot;&gt;.dovenv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Tras importar mongoClient, y definir las variables que se emplearán en la conexión (url a la BBDD, nombre de la BBDD y nombre de la colección) lanzo un &lt;code&gt;mongoClient.connect()&lt;/code&gt; que devuelve bien un error de conexión o abre la conexión (cliente) al gestor de BBDD MongoDB. Luego, con  &lt;code&gt;const db = database.db(db_name);&lt;/code&gt; obtengo acceso a la BBDD, y seguidamente hago una consulta con &lt;code&gt;db.collection(collection).find()&lt;/code&gt;. Una vez obtengo el resultado de la búsqueda (en este caso todos los documentos dentro de la colección de la BBDD), los muestro por consola y cierro la base de datos con &lt;code&gt;database.close();&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Pero si deseo hacer otra búsqueda, o en el módulo tengo una serie de rutas, todas ellas apuntando a una consulta a la BBDD, el número de aperturas y cierres de la conexión se multiplica por el número de consultas. Esto en una página personal o con poco tráfico es sostenible, pero no lo es para grandes flujos de acceso o incluso para situaciones de picos concretos de acceso al servidor (horas de más tráfico, momentos del año donde las consultas se incrementan, por ejemplo cuando se solicitan los resultados de un evento, las notas de fin de curso, una noticia que ha tenido popularidad o alcance…).&lt;/p&gt;
&lt;p&gt;Mantener la conexión abierta para distintas consultas en un módulo es fácil, pero, ¿cómo abrirla a través de los distintos módulos de la aplicación?&lt;/p&gt;
&lt;h2 id=&quot;primer-acercamiento-importar-y-conectar&quot;&gt;Primer acercamiento: Importar y conectar&lt;/h2&gt;
&lt;p&gt;Mi primera opción fue que si voy a emplear la conexión en distintos módulos debía extraer el proceso de conexión a un módulo a parte y luego importarlo allá donde lo necesite, y dicho y hecho:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;NODE_ENV&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;production&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;dotenv&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;config&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; MongoClient&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;mongodb&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).MongoClient;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; url&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;process&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_HOST&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}:${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;process&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_PORT&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}/`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; db_name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_DATABASE&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; loadDB&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; async&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    try&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; client&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; MongoClient.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;connect&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(url);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; db&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; client.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;db&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(db_name);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; db;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (err) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(err);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;module&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;exports&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; loadDB;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Este módulo realiza lo mismo que en el ejemplo anterior, es decir, abre una conexión a MongoDB, pero lo hace exportando la función asíncrona &lt;code&gt;loadDB&lt;/code&gt; para que pueda ser llamada desde otros módulos con:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; loadDB&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;../services/DB&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; db;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; collection&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;products&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; db &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; loadDB&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;())();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;db.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;collection&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(collection).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;find&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;toArray&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;result&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (err) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;throw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; err;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(result);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Tras cargar &lt;code&gt;loadDB&lt;/code&gt;, declaro la variable de ámbito global &lt;code&gt;db&lt;/code&gt; que contendrá la conexión a la BBDD, y en la línea:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; db &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; loadDB&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;())();&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ejecuto la función asíncrona &lt;code&gt;loadDB()&lt;/code&gt; para obtener la conexión que se guardará en &lt;code&gt;db&lt;/code&gt;, y ya puedo hacer la consulta con &lt;code&gt;db.collection(collection).find()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Esta consulta podría formar parte de una ruta de &lt;strong&gt;express&lt;/strong&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; express&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;express&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; router&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; express.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Router&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; loadDB&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;../services/DB&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; db;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; collection&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;products&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; db &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; loadDB&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;())();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;router.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;/ejemplo&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, (&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;req&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;res&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    db.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;collection&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(collection).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;find&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;toArray&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;result&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (err) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;throw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; err;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        res.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;json&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(result);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;module&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;exports&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; router;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pero claro, esta forma de proceder implica abrir una conexión por cada módulo de rutas que use la función loadDB. No es lo que busco.&lt;/p&gt;
&lt;h1 id=&quot;alternativa-función-callback-al-rescate&quot;&gt;Alternativa: función &lt;em&gt;callback&lt;/em&gt; al rescate&lt;/h1&gt;
&lt;p&gt;¿Qué tal si, en vez de intentar traer a cada módulo la conexión a la BBDD llevo las rutas a la función que abre la conexión directamente mediante una función &lt;em&gt;callback&lt;/em&gt;? Veamos…&lt;/p&gt;
&lt;p&gt;Para que todas las rutas puedan usar la variable &lt;code&gt;db&lt;/code&gt; que se declara cuando se lleva a cabo la conexión, podría establecer una única conexión a la base de datos desde index.js (o app.js) osea, desde el fichero principal de la aplicación &lt;strong&gt;Node.js&lt;/strong&gt;, y referenciar las rutas dentro de una función &lt;em&gt;callback&lt;/em&gt; que le pase al módulo encargado de abrir la conexión.&lt;/p&gt;
&lt;p&gt;Esta idea fue la que me propuso &lt;strong&gt;ZeroBl&lt;/strong&gt;, que se tomó el tiempo de responder a mis preguntas en un foro de Discord, y tras pasarme el código que él usa para establecer su conexión, y buscar un poco más de información en StackOverflow, el resultado fue el siguiente:&lt;/p&gt;
&lt;h2 id=&quot;módulo-de-conexión-a-la-bbdd&quot;&gt;Módulo de conexión a la BBDD&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;NODE_ENV&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;production&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;dotenv&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;config&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; MongoClient&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;mongodb&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).MongoClient;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; url&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;process&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_HOST&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}:${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;process&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_PORT&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}/`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; db_name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_DATABASE&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; _db;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; _client;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; connectDB&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;callback&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    try&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        MongoClient.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;connect&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(url, {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            useNewUrlParser: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            useUnifiedTopology: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;client&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            _client &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; client;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            _db &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; client.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;db&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(db_name);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; callback&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(err, client);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (err) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        throw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; err;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; getDB&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (_db) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; _db;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    throw&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;BBDD no encontrada.&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; disconnectDB&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (_db) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; _client.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;close&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    throw&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;BBDD no encontrada.&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;module&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;exports&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { connectDB, getDB, disconnectDB };&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Como se aprecia, este módulo devuelve tres funciones: &lt;code&gt;connectDB&lt;/code&gt; que abre la conexión, &lt;code&gt;getDB&lt;/code&gt; que obtiene la conexión a la BBDD, y &lt;code&gt;disconnectDB&lt;/code&gt;, que cierra la conexión a la BBDD.&lt;/p&gt;
&lt;p&gt;A &lt;code&gt;connectDB&lt;/code&gt; le paso un &lt;code&gt;callback&lt;/code&gt; que se ejecutará en el ámbito donde está viva la conexión. Igual deberemos obtener la referencia a &lt;code&gt;_db&lt;/code&gt; en cada módulo que usemos. Lo voy a explicar enseguida.&lt;/p&gt;
&lt;p&gt;Con &lt;code&gt;disconnectDB&lt;/code&gt; puedo cerrar la conexión a la BBDD desde cualquier parte del programa, pero también debo importarlo si queremos usarlo.&lt;/p&gt;
&lt;h2 id=&quot;el-indexjs&quot;&gt;El index.js&lt;/h2&gt;
&lt;p&gt;O cualquier otro js que haga las veces de inicio de nuestra app:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;NODE_ENV&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;production&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;dotenv&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;config&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; express&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;express&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; app&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; express&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; port&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;PORT&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; mongoDB&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;./services/DB&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;mongoDB.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;connectDB&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;client&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (err) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;throw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; err;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // Ej. http:localhost:3000/ejemplo&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; RouteEjemplo&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;./routes/ejemplo&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    app.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;/ejemplo&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, RouteEjemplo);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // otras rutas...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // Ej. http:localhost:3000/exit&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    app.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;/exit&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;req&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;res&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        client.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;close&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        res.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;end&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;Fin&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        process.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;kill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(process.pid, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;SIGTERM&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    app.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;req&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;res&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        res.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;status&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;404&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;send&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;Error 404: No encontrado.&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    app.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;req&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;res&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(err.stack);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; status&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; err.status &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 500&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        res.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;status&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(status).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;send&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;`Error ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;status&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}: ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}.`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; server&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; app.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;listen&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(port, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;`Servidor levantado en el puerto ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;port&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}.`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    process.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;SIGTERM&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        server.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;close&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;Proceso terminado.&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Importo el módulo de &lt;code&gt;mongoDB&lt;/code&gt; y conecto a la BBDD con:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;mongoDB.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;connectDB&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;client&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // Función callback&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Función a la que le paso como &lt;em&gt;callback&lt;/em&gt; todo el manejo de rutas, e incluso levanto el servidor. Recuerda que esta función se ejecutará tras establecer la conexión en la línea:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; callback&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(err, client);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Al ejecutar la función obtengo dos posibles valores, o bien un error, o bien el cliente para la conexión. Esto me va a permitir hacer uso del cliente desde la misma función &lt;em&gt;callback&lt;/em&gt;, para, por ejemplo, cerrar la conexión, como ocurre en la ruta &lt;code&gt;/exit&lt;/code&gt; en:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;client.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;close&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Usar una ruta para cerrar la aplicación por supuesto es un ejemplo ilustrativo, y no es la mejor forma de hacerlo. ;)&lt;/p&gt;
&lt;p&gt;Si quiero cerrar la aplicación desde dentro de un módulo de, por ejemplo, una ruta, debo usar &lt;code&gt;disconnectDB()&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;la-ruta-de-ejemplo&quot;&gt;La ruta de ejemplo&lt;/h2&gt;
&lt;p&gt;Como dije, para poder utilizar la BBDD en las distintas rutas o en los módulos de la aplicación, debo importar la referencia a &lt;code&gt;db&lt;/code&gt; en cada módulo con:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; mongoDB&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;../services/DB&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; db&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; mongoDB.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getDB&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;y a partir de ahí puedo usar &lt;code&gt;db&lt;/code&gt; en todo el módulo. Así de simple.&lt;/p&gt;
&lt;p&gt;Esto es posible porque, como hemos visto, estamos llamado a esta ruta dentro del &lt;em&gt;callback&lt;/em&gt; que pasamos a la función que abre la conexión.&lt;/p&gt;
&lt;h1 id=&quot;en-resumen&quot;&gt;En resumen&lt;/h1&gt;
&lt;p&gt;Mediante un módulo que devuelve tres funciones podemos abrir la conexión a la BBDD (recibiendo y ejecutando un &lt;em&gt;callback&lt;/em&gt;) obtener la referencia a la BBDD y cerrar la conexión a la BBDD.&lt;/p&gt;
&lt;p&gt;Dentro del &lt;em&gt;callback&lt;/em&gt; definimos las rutas (&lt;code&gt;app.use&lt;/code&gt;) que van a hacer uso de la BBDD, y en cada módulo donde se defina la ruta o las sub-rutas, deberemos obtener la referencia a la BBDD para poder usarla.&lt;/p&gt;
&lt;p&gt;En este &lt;a href=&quot;https://stackoverflow.com/questions/24621940/how-to-properly-reuse-connection-to-mongodb-across-nodejs-application-and-module&quot;&gt;enlace a StackOverflow&lt;/a&gt; (&lt;em&gt;en inglés&lt;/em&gt;) podrás obtener más información y alternativas a esta solución.&lt;/p&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/mongodb.B38n9K_s_1aeGYn.webp"/><category>código</category><category>javascript</category><category>node.js</category><category>express</category><category>mongodb</category><author>JavGuerra</author></item><item><title>Usando populate con paginate y filtrando los resultados</title><link>https://javguerra.github.io/blog/populate-paginate-fitrado</link><guid isPermaLink="true">https://javguerra.github.io/blog/populate-paginate-fitrado</guid><description>Cómo relacionar colecciones cuando se usa mongoose-paginate-v2</description><pubDate>Sat, 29 Oct 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/mongoose.yK9gFAu8_Z1xJtaI.webp&quot; alt=&quot;mongoose-paginate-v2&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#node.js&lt;/em&gt;, &lt;em&gt;#mongodb&lt;/em&gt;, &lt;em&gt;#mongoose&lt;/em&gt;, &lt;em&gt;#paginate&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Si bien mongodb tiene formas de obtener resultados paginados (limit, skip), el módulo mongoose-paginate-v2 de mongoose nos ahorra tiempo y código a la hora de preparar y usar los datos paginados obtenidos de las búsquedas en nuestras bases de datos, devolviendo información complementaria muy cómoda, pero ¿cómo podemos usar la paginación cuando tenemos relaciones entre colecciones? En esta entrada explicaré cómo paginar resultados agregados entre colecciones como si usásemos aggregate en mongodb o populate en mongoose, y además cómo filtrar búsquedas agregadas y paginadas con este módulo.&lt;/p&gt;
&lt;h1 id=&quot;el-ejemplo&quot;&gt;El ejemplo&lt;/h1&gt;
&lt;p&gt;Imaginemos que tenemos dos colecciones en una BBDD mongodb, una de &lt;code&gt;libros&lt;/code&gt; y otra de &lt;code&gt;autores&lt;/code&gt;, y un dato en cada documento de la colección libros llamado &lt;code&gt;autor&lt;/code&gt; que sirve para contener la información agregada del autor en la colección libros. En el &lt;em&gt;schema&lt;/em&gt;, el dato &lt;code&gt;autor&lt;/code&gt; podría tener esta forma:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    autor&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        ref&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: Schema.Types.ObjectId, &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;ref&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;Autor&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        nombre&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: String&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La propiedad &lt;code&gt;ref&lt;/code&gt; es la que «tenderá el puente» entre ambas colecciones, y contendrá el &lt;code&gt;_id&lt;/code&gt; del documento a relacionar de la colección &lt;code&gt;autores&lt;/code&gt;. La propiedad &lt;code&gt;nombre&lt;/code&gt; contendrá, como se espera, el nombre del autor. Si bien este dato estará también en la colección &lt;code&gt;autores&lt;/code&gt;, y puede ser redundante cuando agregamos los resultados, el dato tiene su utilidad, pues nos permite realizar el filtrado de libros por autor incluso sin realizar la agregación.&lt;/p&gt;
&lt;p&gt;Una búsqueda haciendo uso de populate tendría esta forma:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;Libro.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;find&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;( filtro ).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;populate&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;( &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;autor.ref&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;exec&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;donde &lt;code&gt;filtro&lt;/code&gt; es un objeto que contendrá los criterios de búsqueda, y &lt;code&gt;autor.ref&lt;/code&gt; es la necesaria referencia para poder llevar a cabo la agregación de datos de la colección &lt;code&gt;autores&lt;/code&gt; en &lt;code&gt;libros&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Si queremos emplear el módulo &lt;code&gt;mongoose-paginate-v2&lt;/code&gt; para paginar los resultados de la búsqueda, esta quedaría de la siguiente forma:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;Libro.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;paginate&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(filtro, { page, limit });&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;donde &lt;code&gt;page&lt;/code&gt; indica la página de resultados a obtener y &lt;code&gt;limit&lt;/code&gt; el número de resultados por página.&lt;/p&gt;
&lt;p&gt;Pero sólo nos devolverá los datos de la colección &lt;code&gt;autores&lt;/code&gt;, sin agregar los datos de la colección &lt;code&gt;libros&lt;/code&gt;. ¿Cómo se haría esto?&lt;/p&gt;
&lt;h1 id=&quot;agregando-y-paginando&quot;&gt;Agregando y paginando&lt;/h1&gt;
&lt;p&gt;Hemos visto que paginate acepta dos parámetros, los criterios de búsqueda (filtro) y las opciones (page, limit). Otra opción que podemos añadir a paginate es &lt;code&gt;populate&lt;/code&gt;. Para hacer una búsqueda agregada como la del ejemplo, usaríamos:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;Libro.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;paginate&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(filtro, { page, limit, populate: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;autor.ref&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; });&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;de esta forma podemos obtener un resultado con la información de ambas colecciones.&lt;/p&gt;
&lt;p&gt;La opción populate permite también otras opciones. Imaginemos que en la agregación queremos obviar el dato &lt;code&gt;nombre&lt;/code&gt; de la colección &lt;code&gt;autores&lt;/code&gt; que ya tenemos en la colección &lt;code&gt;libros&lt;/code&gt;. Podemos pasarle a &lt;code&gt;populate&lt;/code&gt; un objeto de la siguiente forma:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;Libro.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;paginate&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(filtro, { page, limit, populate: {path: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;autor.ref&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, select: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;-nombre&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos; })&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;donde &lt;code&gt;select: &apos;-nombre&apos;&lt;/code&gt;, que va con un signo menos (-) delante, indica que ese dato no será requerido. Véase también que, para incluir la referencia a la colección, dentro del objeto se usa &lt;code&gt;path: &apos;autor.ref&apos;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Puedes obtener más información sobre las &lt;a href=&quot;https://mongoosejs.com/docs/api.html#query_Query-populate&quot;&gt;opciones de populate&lt;/a&gt; en el manual on-line.&lt;/p&gt;
&lt;h1 id=&quot;filtrando&quot;&gt;Filtrando&lt;/h1&gt;
&lt;p&gt;Decía más arriba que nos puede interesar hacer un filtrado en la búsqueda sobre nuestra base de datos por el nombre del autor, que es un dato dentro de otro dato, pero antes recordaré cómo buscar por uno o varios datos de la colección.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; filtro&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (titulo) filtro.titulo &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { $regex: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;`.*${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;titulo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}.*`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (precio) filtro.precio &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { $lte: precio };&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Este código creará un objeto &lt;code&gt;filtro&lt;/code&gt; que permitirá que busquemos en la colección &lt;code&gt;libros&lt;/code&gt; por título y precio, ya que, si estos datos de búsqueda existen, con &lt;code&gt;filtro.titulo&lt;/code&gt; y &lt;code&gt;filtro.precio&lt;/code&gt; añadimos ambas propiedades al objeto filtro que usaremos en la búsqueda de la forma en que hemos visto en todos los ejemplos anteriores. (Nota: entiéndase que podríamos tener libros con el mismo título y distinto precio según la editorial o la colección editorial).&lt;/p&gt;
&lt;p&gt;Con &lt;code&gt;{ $regex: `.*${titulo}.*/` }&lt;/code&gt; buscamos por la expresión regular dada, en cambio con &lt;code&gt;$lte: precio&lt;/code&gt; buscamos por un valor igual o menor al proporcionado. Ver más información sobre &lt;a href=&quot;https://www.mongodb.com/docs/manual/reference/operator/&quot;&gt;operadores de búsqueda en mongodb&lt;/a&gt; en el manual on-line.&lt;/p&gt;
&lt;p&gt;Esto permitirá que:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;Libro.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;paginate&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(filtro, { page, limit, populate: {path: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;autor.ref&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, select: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;-nombre&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos; })&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;devuelva aquellos documentos de la colección &lt;code&gt;libros&lt;/code&gt; que tengan coincidencias con el &lt;code&gt;filtro&lt;/code&gt; indicado, es decir, que contengan en el título el texto &lt;code&gt;titulo&lt;/code&gt; indicado y cuyo precio sea igual o menor al &lt;code&gt;precio&lt;/code&gt; indicado.&lt;/p&gt;
&lt;h2 id=&quot;consulta-sobre-datos-anidados&quot;&gt;Consulta sobre datos anidados&lt;/h2&gt;
&lt;p&gt;Teniendo claro lo anterior, acceder al dato &lt;code&gt;nombre&lt;/code&gt; dentro de &lt;code&gt;autor&lt;/code&gt; no es complicado, pero para referenciar el dato tendremos que usar lo siguiente:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; filtro&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (nombre) filtro[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;autor.nombre&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { $regex: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;`.*${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;nombre&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}.*`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; };&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Uso aquí los corchetes &lt;code&gt;[]&lt;/code&gt; porque para poder usar el filtro en mongodb debo pasarle la propiedad al objeto filtro de esta forma: &lt;code&gt;{ &quot;autor.nombre&quot; : { $regex: `.*${nombre}.*` } }&lt;/code&gt; como se indica en la sección &lt;a href=&quot;https://www.mongodb.com/docs/manual/tutorial/query-embedded-documents/&quot;&gt;consulta sobre documentos incrustados/anidados&lt;/a&gt; del manual online.&lt;/p&gt;
&lt;p&gt;Este filtro devolverá aquellos documentos de la colección &lt;code&gt;libros&lt;/code&gt; que, dentro del dato &lt;code&gt;autor&lt;/code&gt;, contengan el nombre dado dentro del dato anidado &lt;code&gt;nombre&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/mongoose-paginate-v2&quot;&gt;mongoose-paginate-v2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mongoosejs.com/docs/api.html#query_Query-populate&quot;&gt;Opciones de populate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.mongodb.com/docs/manual/reference/operator/&quot;&gt;Operadores de búsqueda en mongodb&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.mongodb.com/docs/manual/tutorial/query-embedded-documents/&quot;&gt;Consulta sobre documentos incrustados/anidados&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/mongoose.yK9gFAu8_Z1xJtaI.webp"/><category>código</category><category>javascript</category><category>node.js</category><category>mongodb</category><category>mongoose</category><category>paginate</category><author>JavGuerra</author></item><item><title>Generar enlaces dinámicos de imágenes almacenadas en MongoDB</title><link>https://javguerra.github.io/blog/rutas-dinamicas-imagenes-mongodb</link><guid isPermaLink="true">https://javguerra.github.io/blog/rutas-dinamicas-imagenes-mongodb</guid><description>Conseguir que nuestros datos no dependan de una ubicación estática</description><pubDate>Sun, 06 Nov 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/dynamic_links.BDCzFkfb_1Co5pD.webp&quot; alt=&quot;Enlaces dinámicos&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#node.js&lt;/em&gt;, &lt;em&gt;#mongodb&lt;/em&gt;, &lt;em&gt;#imágenes&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Las bases de datos a menudo contienen referencias a recursos que no son almacenados en su misma estructura. Un claro ejemplo de ello son las fotografías o imágenes que acompañan a los productos de un catálogo. En tal caso, guardar la información es sencillo, es suficiente con almacenar la ruta completa al recurso en un campo de tipo &lt;em&gt;String&lt;/em&gt;, pero, ¿que ocurre si, presumiblemente, nuestros datos van a cambiar de ubicación, o van a correr en distintas instancias o en diferentes hospedajes? En ese caso, lo recomendable es almacenar la información del nombre del recurso en la BBDD, y entonces tendremos dos alternativas para generar el enlace completo: modificar los datos de la BBDD mediante un &lt;em&gt;script&lt;/em&gt; para que la url al recurso sea la adecuada cada vez que cambiamos de ubicación los datos, o bien generar la ruta al recurso de forma dinámica, al vuelo, cuando se realizan las consultas. Vamos a ver aquí la segunda.&lt;/p&gt;
&lt;h1 id=&quot;el-ejemplo&quot;&gt;El ejemplo&lt;/h1&gt;
&lt;p&gt;Partimos de la siguiente premisa. En las variables globales del sistema tenemos almacenadas la ruta y el puerto del servidor donde están ubicadas las imágenes, que es la información susceptible de cambiar de lugar. Tal vez estos datos estén disponibles mediante &lt;a href=&quot;https://www.npmjs.com/package/dotenv&quot;&gt;dotenv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Tomemos como referencia el ejemplo de la &lt;a href=&quot;/blog/populate-paginate-fitrado&quot;&gt;entrada anterior&lt;/a&gt;. Dos colecciones relacionadas, &lt;code&gt;libros&lt;/code&gt; y &lt;code&gt;autores&lt;/code&gt;, y en las que queremos incluir un dato en cada documento de la colección libros con la foto de portada del libro, y un dato con la foto del autor en cada documento de la colección autores. Algo como:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;libro&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    portada&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;don-quijote.png&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;autor&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    foto&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;cervantes.jpg&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;obviamente, tanto la colección libros como la conección autores tendrán otros datos, no sólo la portada o la foto.&lt;/p&gt;
&lt;h1 id=&quot;la-ruta&quot;&gt;La ruta&lt;/h1&gt;
&lt;p&gt;Para poder acceder a la portada del libro, necesitamos completar la ruta a la imagen. En este ejemplo usaremos el dominio &lt;code&gt;lalibreria2022.com&lt;/code&gt; al que se accede por el porto &lt;code&gt;80&lt;/code&gt;. Esta información la tenemos almacenada en un fichero &lt;code&gt;.env&lt;/code&gt; de nuestra aplicación de la siguiente forma:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;HOST=&apos;https://lalibreria2022.com&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;PORT=80&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Y asumo que las portadas se almacenan en una carpeta llamada &lt;code&gt;portadas&lt;/code&gt;, y las fotos en otra llamada &lt;code&gt;fotos&lt;/code&gt;.
De esta forma, para acceder a la imagen &lt;code&gt;don-quijote.png&lt;/code&gt; debemos completar la siguiente ruta:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;HOST + &apos;:&apos; + PORT + &apos;/&apos; + &apos;portadas&apos; + &apos;/&apos; + &apos;don-quijote.png&apos;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;y obtendríamos:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;https://lalibreria2022.com:80/portadas/don-quijote.png&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&quot;alterando-los-resultados&quot;&gt;Alterando los resultados&lt;/h1&gt;
&lt;p&gt;Cuando llevamos a cabo las búsquedas de información sobre la BBDD, esta nos devolverá, como ya sabemos, el nombre del recurso (‘don-quijote.png’), pero queremos que la BBDD devuelva dinámicamente la ruta antes mencionada. Para ello hay que recorrer el resultado obtenido y hacer cambios sobre los datos. Un &lt;code&gt;forEach()&lt;/code&gt; es suficiente.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; insertarRutas&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; datos&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; url&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;HOST&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;:&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;PORT&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;/&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    datos.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;forEach&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;( &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;elemento&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; elemento.portada &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; url &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;portadas/&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; elemento.portada );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; data;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Tras cada búsqueda, aplicando esta función al resultado, recorro todos los documentos de la colección (&lt;code&gt;datos&lt;/code&gt;) y cambio el valor del dato &lt;code&gt;portada&lt;/code&gt; en cada documento.&lt;/p&gt;
&lt;h1 id=&quot;también-con-resultados-agregados&quot;&gt;También con resultados agregados&lt;/h1&gt;
&lt;p&gt;Cuando llevamos a cabo consultas agregadas, el proceso es similar. En una consulta donde obtenemos los libros y las referencias a sus respectivos autores, debemos repetir el proceso también para el dato &lt;code&gt;foto&lt;/code&gt; de la colección &lt;code&gt;autores&lt;/code&gt;, pero hay que tener en cuenta lo siguiente:&lt;/p&gt;
&lt;p&gt;{: .box-note}
&lt;strong&gt;Nota:&lt;/strong&gt; Cuando recorremos una colección agregada lo hacemos sobre una colección y sobre referencias a otra colección, es decir, si hay varios libros de un mismo autor, aunque los datos del autor se muestren en varios libros agregados, solo están almacenados una vez.&lt;/p&gt;
&lt;p&gt;Esto tiene importancia porque, al realizar el cambio de la ruta de la foto del autor, estaríamos cambiándola tantas veces como libros existan, y generando entonces una url errónea con rutas repetidas. Si tenemos dos libros de Cervantes, la ruta a la foto podría verse así:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;https://lalibreria2022.com:80/fotos/https://lalibreria2022.com:80/fotos/cervantes.jpg&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Para evitar esto, debemos implementar el siguiente código, en el que se incluyen ambos casos, el de la portada del libro y el de la foto del autor:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; insertarRutas&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; datos&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; url&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;HOST&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;:&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;PORT&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;/&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    datos.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;forEach&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;elemento&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        elemento.portada &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; url &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;portadas/&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; elemento.portada;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;elemento.autor.ref.foto.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;includes&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(url)) &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;             elemento.autor.ref.foto &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; url &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;fotos/&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; elemento.autor.ref.foto;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; data;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con el condicional (&lt;code&gt;if&lt;/code&gt;) me aseguro de que la foto no contiene ya la ruta completa, y si no es así, la completa.&lt;/p&gt;
&lt;h1 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/populate-paginate-fitrado&quot;&gt;Usando populate con paginate y filtrando los resultados&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/dynamic_links.BDCzFkfb_1Co5pD.webp"/><category>código</category><category>javascript</category><category>node.js</category><category>mongodb</category><category>imágenes</category><author>JavGuerra</author></item><item><title>Tienda 8 bits</title><link>https://javguerra.github.io/blog/tienda-8-bits</link><guid isPermaLink="true">https://javguerra.github.io/blog/tienda-8-bits</guid><description>Proyecto de graduación del Bootcamp Full Stack Web Developer</description><pubDate>Fri, 18 Nov 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/tienda-8-bits.BGpB2fQx_Znqyrs.webp&quot; alt=&quot;Banner tienda 8 bits&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#portfolio&lt;/em&gt;, &lt;em&gt;#web&lt;/em&gt;, &lt;em&gt;#formación&lt;/em&gt;, &lt;em&gt;#becas&lt;/em&gt;, &lt;em&gt;#node.js&lt;/em&gt;, &lt;em&gt;#express&lt;/em&gt;, &lt;em&gt;#react&lt;/em&gt;, &lt;em&gt;#mongodb&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#accesibilidad&lt;/em&gt;, &lt;em&gt;#responsive&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Durante el año 2022 cursé el &lt;a href=&quot;/blog/beca-santander-fswd&quot;&gt;Bootcamp de Desarrollo Web Full Stack&lt;/a&gt; que &lt;a href=&quot;https://www.becas-santander.com/es/index.html&quot;&gt;Becas Santander&lt;/a&gt; llevó a cabo en colaboración con &lt;a href=&quot;https://www.universia.net/es/empleo&quot;&gt;Fundación Universia&lt;/a&gt;, &lt;a href=&quot;https://www.indracompany.com/&quot;&gt;Indra&lt;/a&gt; y &lt;a href=&quot;https://www.thebridge.tech/&quot;&gt;The Bridge&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.badared.com/proyecto/tienda8bits/&quot;&gt;&lt;button&gt;Ir a la aplicación on-line&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;El día 17 de noviembre finalizó la formación con un acto de entrega de diplomas on-line en el que tuve ocasión de mostrar mi proyecto final «Tienda 8 bits» junto con Alex, otro de mis compañeros, quien también expuso su proyecto.&lt;/p&gt;
&lt;p&gt;A parte de los compañeros y los profesores, asistieron al evento Alejandra Cuenca y Diego Díaz por parte de The Bridge, Cristina Soriano por Minsait/Indra, y Beatriz Arribas y Carlos Sánchez por Universia.&lt;/p&gt;
&lt;h2 id=&quot;video&quot;&gt;Video&lt;/h2&gt;
&lt;p&gt;El evento se llevó a cabo de forma presencial y on-line, y de él he rescatado el video de mi presentación que comparto a continuación.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Video de presentación&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/tienda.png&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://youtu.be/XlswjqhxJZ8&quot;&gt;&lt;button&gt;Ver el video en YouTube&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;descripción-técnica&quot;&gt;Descripción técnica&lt;/h2&gt;
&lt;h3 id=&quot;back-end&quot;&gt;Back end&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Tecnologías empleadas&lt;/strong&gt;: Node.js + Express + MongoDB + Mongoose&lt;br&gt;
&lt;strong&gt;Módulos&lt;/strong&gt;: compression, cors, helmet, dotenv, nodemon, mongoose-paginator-v2&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Características destacadas de la API&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Emplea módulos ESM.&lt;/li&gt;
&lt;li&gt;Está preparada para el versionado de la API.&lt;/li&gt;
&lt;li&gt;Está preparada para el uso de BBDD MongoDB local o en remoto (config.js).&lt;/li&gt;
&lt;li&gt;Preserva la seguridad del acceso a la API con el uso del módulo helmet.&lt;/li&gt;
&lt;li&gt;Devuelve las rutas de los enlaces a las fotos y logos dinámicamente.&lt;/li&gt;
&lt;li&gt;Cuenta con documentación de la API.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;front-end&quot;&gt;Front end&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Tecnologías empleadas&lt;/strong&gt;: React + Vite, axios, react-router-dom, react-hook-form&lt;br&gt;
&lt;strong&gt;Módulos propios&lt;/strong&gt;: setSpin, inactiveBtn, compareTwoObjects&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Características destacadas de la App&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;El diseño es adaptable (responsive) según el dispositivo.&lt;/li&gt;
&lt;li&gt;CSS propio. No usa frameworks.&lt;/li&gt;
&lt;li&gt;Es accesible (revisado con el complemento &lt;a href=&quot;https://wave.webaim.org/&quot;&gt;WAVE&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Utiliza fuentes de Google Font en los títulos para preservar la accesibilidad.&lt;/li&gt;
&lt;li&gt;Implementa el protocolo &lt;a href=&quot;https://ogp.me/&quot;&gt;Open Graph&lt;/a&gt; para la correcta inserción de la web en RRSS.&lt;/li&gt;
&lt;li&gt;Es compatible con Progessive Web Aplication (&lt;a href=&quot;https://developer.mozilla.org/es/docs/Web/Progressive_web_apps&quot;&gt;PWA&lt;/a&gt;) a través de fichero &lt;a href=&quot;https://developer.mozilla.org/es/docs/Web/Manifest&quot;&gt;manifest.json&lt;/a&gt;, por lo que la página puede ser instalada en dispositivos móviles como una web app.&lt;/li&gt;
&lt;li&gt;Ha sido probada con los navegadores web Firefox y Chrome.&lt;/li&gt;
&lt;li&gt;Tratamiento de imágenes con software libre: Gimp e InkScape.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;fuentes&quot;&gt;Fuentes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Wikipedia&lt;/li&gt;
&lt;li&gt;Enciclopedia «Mi Computer», editorial Delta, 1984.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;licencias&quot;&gt;Licencias&lt;/h3&gt;
&lt;p&gt;Sobre el código fuente: &lt;a href=&quot;https://github.com/JavGuerra/tienda-8-bits/blob/main/LICENSE&quot;&gt;GNU GENERAL PUBLIC LICENSE Version 3&lt;/a&gt;&lt;br&gt;
Sobre el contenido de la web: &lt;a href=&quot;https://creativecommons.org/licenses/by-sa/3.0/es/&quot;&gt;(CC) BY-SA 3.0&lt;/a&gt;&lt;br&gt;
Sobre las fotos: Son propiedad de sus respectivos autores.&lt;br&gt;
Sobre las fuentes de letra: &lt;a href=&quot;https://fonts.google.com/&quot;&gt;Google Fonts&lt;/a&gt;&lt;br&gt;
Sobre los iconos: &lt;a href=&quot;https://heroicons.com/&quot;&gt;Heroicons&lt;/a&gt;&lt;br&gt;
Material usado sin ánimo de lucro bajo criterios didácticos y formativos.&lt;/p&gt;
&lt;h3 id=&quot;acceder-a-la-aplicación&quot;&gt;Acceder a la aplicación&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/JavGuerra/tienda-8-bits/0d3d3a968787a438379d003fe31aaede91011e40/qrcode.svg&quot; alt=&quot;Código QR&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.badared.com/proyecto/tienda8bits/&quot;&gt;&lt;button&gt;Ir a la aplicación on-line&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://javguerra.badared.com/proyecto/tienda8bits/&quot;&gt;Aplicación on-line&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://api-tienda8bits.up.railway.app/&quot;&gt;Documentación de la API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/tienda-8-bits/blob/main/enunciado.pdf&quot;&gt;Enunciado de la práctica en PDF&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/tienda-8-bits&quot;&gt;Repositorio en GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://youtu.be/XlswjqhxJZ8&quot;&gt;Video de la presentación en YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/tienda-8-bits/blob/main/presentacion.pdf&quot;&gt;Presentación en PDF&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Artículos informativos elaborados por el autor relacionados con esta práctica&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/populate-paginate-fitrado&quot;&gt;Usando populate con paginate y filtrando los resultados&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/rutas-dinamicas-imagenes-mongodb&quot;&gt;Generar enlaces dinámicos de imágenes almacenadas en MongoDB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/ordenacion-react&quot;&gt;Ordenando resultados en React&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/spinner-loader-asincrono&quot;&gt;Spinner loader asíncrono&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/tienda-8-bits.BGpB2fQx_Znqyrs.webp"/><category>portfolio</category><category>web</category><category>formación</category><category>becas</category><category>node.js</category><category>express</category><category>react</category><category>mongodb</category><category>javascript</category><category>accesibilidad</category><category>responsive</category><author>JavGuerra</author></item></channel></rss>