3 Conexión a base de datos NoSQL¶
Introducción¶
Podemos crear una API en Node JS donde la conexión se realice a través de una base de datos NoSQL. Un base de datos NoSQL es una base de datos no relacional, por la estructura de los datos es m ás flexible y podemos tener datos con diferentes campos.
Un ejemplo de base de datos NoSQL sería MongoDB, el cuál puedes ver sus apuntes para entender bastante mejor. Hay que tener en cuenta que este tipo de base de datos son demasiado flexibles por lo que no tiene un esquema definido y fijo como si pasa con las bases de datos MySQL.
Paquete mongodb¶
Para poder usar MongoDB en un proyecto de Node JS es necesario tener un driver para manager la conexión y las transacciones. El driver oficial es mongodb
y se puede instalar haciendo uso de npm:
Ahora podemos configurar nuestro proyecto con mongoDB, creando una conexión con nuestra base de datos. Para poder realizar nuestra conexión necesitamos crear un objeto cliente:
const client = new MongoClient(uri, {
serverApi: {
version: ServerApiVersion.v1,
strict: true,
deprecationErrors: true
}
})
Una vez creado el cliente, necesitamos un método para que realice las conexiones, si algo fallo cerrará la conexión con el cliente:
async function connect() {
try {
await client.connect()
const database = client.db('database')
return database.collection('movies')
} catch (error) {
console.error('Error connecting to the database')
console.error(error)
await client.close()
}
}
Consulta de datos¶
Podemos consultar todos los datos de una colección e incluso filtrarlos, gracias al método find
.
Info
Casi todo los métodos de estos drivers son bastante parecidos al funcionamiento de dichas funciones dentro del servidor de mongoDB, por lo que si quieres conocer más su funcionamiento visita la página oficial de MongoDB, o nuestro temario de MongoDB
static async getAll({ genre }) {
const db = await connect()
if (genre) {
return db.find({
genre: {
$elemMatch: {
$regex: genre,
$options: 'i'
}
}
}).toArray()
}
return db.find({}).toArray()
}
ObjectId¶
En MongoDB, al insertar un nuevo dato, mongo te crea un ID de forma automática. Este identificador es de tipo ObjectId
por lo que si nosotros deseamos realizar una búsqueda de un elemento de forma directa no podemos hacer la comparación en cadena si no como un objeto de tipo ObjectId
. El driver de mongodb dispone de una clase ObjectId
que nos permite crear objetos de dicho tipo a través de un valor pasado por parámetro:
static async getById({ id }) {
const db = await connect()
const objectId = new ObjectId(id)
return db.findOne({ _id: objectId })
}
Crear un elemento¶
Para crear un elemento, podemos usar el método insertOne
que recibe el objeto que quiere crear. Dicho método te devuelve el objeto creado, incluido el id auto-creado, por lo que podemos devolver el objeto completo para que mostrárselo al usuario que ha realizado la petición a nuestra API:
static async create({ input }) {
const db = await connect()
const { insertedId } = await db.insertOne(input)
return {
id: insertedId,
...input
}
}
Actualizar y eliminar elementos¶
Para actualizar y eliminar un elemento de la base de datos mongodb, podemos usar los métodos deleteOne
y findOneAndUpdate
, respectivamente. En el caso de eliminar necesitaremos el id del objeto a eliminar, y en el caso de actualizar su id, los cambios a realizar. Además podemos tener una opción de que se devuelva el nuevo documento creado a la hora de actualizar y de esta forma comprobar que la actualización se ha hecho de forma correcta y así hacérselo saber al usuario.
Al eliminar nos devuelve un objeto con el número de elementos eliminador, por lo que podemos usar dicho número para comprobar si la eliminación se ha realizado correctamente.
static async delete({ id }) {
const db = await connect()
const objectId = new ObjectId(id)
const { deletedCount } = await db.deleteOne({ _id: objectId })
return deletedCount > 0
}
static async update({ id, input }) {
const db = await connect()
const objectId = new ObjectId(id)
const { ok, value } = await db.findOneAndUpdate({ _id: objectId }, { $set: input }, { returnNewDocument: true })
if (!ok) return false
return value
}