From 2851bd66985f4e1316a078a0633a18b9135263c2 Mon Sep 17 00:00:00 2001 From: sonia Date: Thu, 7 Mar 2024 20:19:21 +0100 Subject: [PATCH] Arreglar el guardado de la pregunta obtenida de wikidata a la base de datos --- questionsService/guardarPreguntaBaseDatos.js | 155 ++++++----- questionsService/obtenerPreguntasBaseDatos.js | 38 ++- questionsService/obtenerPreguntasWikidata.js | 246 ++++++++++-------- questionsService/question-model.js | 4 - questionsService/question-service.js | 7 +- questionsService/questionGeneration.js | 7 +- 6 files changed, 252 insertions(+), 205 deletions(-) diff --git a/questionsService/guardarPreguntaBaseDatos.js b/questionsService/guardarPreguntaBaseDatos.js index b16b7c1d..e1b4da57 100644 --- a/questionsService/guardarPreguntaBaseDatos.js +++ b/questionsService/guardarPreguntaBaseDatos.js @@ -1,77 +1,96 @@ +const mongoose = require('mongoose'); +const Categoria = mongoose.model('Categoria'); +const Pregunta = mongoose.model('Pregunta'); +const Tipos = mongoose.model('Tipos'); +const Respuesta = mongoose.model('Respuesta'); + class GuardarBaseDatos{ - constructor(finalQuestion, choice, category){ - this.finalQuestion = finalQuestion; - this.choice = choice; - this.category = category; + constructor(){ + this.finalQuestion; } - guardarEnBaseDatos(){ - console.log("Guardando pregunta en la base de datos"); + guardarEnBaseDatos(finalQuestion){ + this.finalQuestion = finalQuestion; //primero deberiamos de guardar la categoria - this.guardarCategoria(); + this.guardarCategoria().then(idCategoria => { + // Guardamos el tipo de pregunta + return this.guardarPreguntaTipo(idCategoria); + }).then(idTipo => { + // Guardamos las respuestas incorrectas + this.guardarPrimeraIncorrecta(idTipo); + this.guardarSegundaIncorrecta(idTipo); + this.guardarTerceraIncorrecta(idTipo); + }).catch(error => { + console.error("Error al guardar la categoría o el tipo de pregunta:", error); + }); } guardarCategoria(){ - console.log("Guardando categoria"); - var idCategoria; - - Categoria.findOne({ textoPregunta: this.finalQuestion.category }) - .then(categoriaExistente => { - if (!categoriaExistente) { - // Si no existe ya esa categoria la crea - var nuevaCategoria = new Categoria({ - nombre: this.category, - }); - - //Guardamos la nueva pregunta - nuevaCategoria.save().then(categoriaGuardada => { - //guardamos el id de la categoria nueva - idCategoria = categoriaGuardada._id; - }); - } - - else{ - //guardamos el id de la categoria existente - idCategoria = categoriaExistente._id; - } - }); - - this.guardarPreguntaTipo(idCategoria); + return new Promise((resolve, reject) => { + var idCategoria; + + Categoria.findOne({ nombre: this.finalQuestion.category }) + .then(categoriaExistente => { + if (!categoriaExistente) { + // Si no existe ya esa categoria la crea + var nuevaCategoria = new Categoria({ + nombre: this.finalQuestion.category, + }); + + //Guardamos la nueva pregunta + nuevaCategoria.save().then(categoriaGuardada => { + //guardamos el id de la categoria nueva + idCategoria = categoriaGuardada._id; + resolve(idCategoria); + }); + } + + else{ + //guardamos el id de la categoria existente + idCategoria = categoriaExistente._id; + resolve(idCategoria); + } + }); + }) .catch(error => { + console.error("Error al ejecutar la consulta:", error); + reject(error); // Rechazamos la Promesa con el error + }); } guardarPreguntaTipo(idCategoria){ - console.log("Guardando pregunta y tipo"); - var idTipo; - // Comprobar si la pregunta ya existe - Pregunta.findOne({ textoPregunta: this.finalQuestion.question }) - .then(preguntaExistente => { - if (!preguntaExistente) { - // Si no existe la pregunta, se crea - var nuevaPregunta = new Pregunta({ - textoPregunta: this.finalQuestion.question, - respuestaCorrecta: this.finalQuestion.correct, - categoria: idCategoria - }); - - // Guardar la nueva pregunta - nuevaPregunta.save() - .then(preguntaGuardada => { - - // Comprobar si existe el tipo de la pregunta y asociarlo - Tipos.findOne({ nombreTipo: this.choice }) - .then(tipoExistente => { - if (!tipoExistente) { - // Si no existe el tipo, se crea - var nuevoTipo = new Tipos({ - idPreguntas: [preguntaGuardada._id], - nombreTipo: this.choice - }); - + return new Promise((resolve, reject) => { + var idTipo; + // Comprobar si la pregunta ya existe + Pregunta.findOne({ textoPregunta: this.finalQuestion.question }) + .then(preguntaExistente => { + if (!preguntaExistente) { + // Si no existe la pregunta, se crea + var nuevaPregunta = new Pregunta({ + textoPregunta: this.finalQuestion.question, + respuestaCorrecta: this.finalQuestion.correct, + categoria: idCategoria + }); + + // Guardar la nueva pregunta + nuevaPregunta.save() + .then(preguntaGuardada => { + + // Comprobar si existe el tipo de la pregunta y asociarlo + Tipos.findOne({ nombreTipo: this.finalQuestion.type }) + .then(tipoExistente => { + if (!tipoExistente) { + // Si no existe el tipo, se crea + var nuevoTipo = new Tipos({ + idPreguntas: [preguntaGuardada._id], + nombreTipo: this.finalQuestion.type + }); + // Guardar el nuevo tipo nuevoTipo.save().then(tipoGuardado => { //guardamos el id del tipo idTipo = tipoGuardado._id; + resolve(idTipo); }); } else { @@ -81,27 +100,27 @@ class GuardarBaseDatos{ tipoExistente.save().then(tipoGuardado => { //guardamos el id del tipo idTipo = tipoGuardado._id; + resolve(idTipo); }); } }); }); } + }).catch(error => { + console.error("Error al ejecutar la consulta:", error); + reject(error); // Rechazamos la Promesa con el error + }); }); - - this.guardarPrimeraIncorrecta(idTipo); - this.guardarSegundaIncorrecta(idTipo); - this.guardarTerceraIncorrecta(idTipo); } guardarPrimeraIncorrecta(idTipo){ - console.log("Guardando primera incorrecta"); //comprobar si la primera respuesta existe ya en la base de datos Respuesta.findOne({ textoRespuesta: this.finalQuestion.incorrect1 }) .then(respuestaExistente => { if (!respuestaExistente) { // Si no existe ya esa pregunta la crea var nuevaRespuesta = new Respuesta({ - textoRespuesta: this.finalQuestion.question, + textoRespuesta: this.finalQuestion.incorrect1, tipos: [idTipo] }); @@ -121,14 +140,13 @@ class GuardarBaseDatos{ } guardarSegundaIncorrecta(idTipo){ - console.log("Guardando segunda incorrecta"); //comprobar si la segunda respuesta existe ya en la base de datos Respuesta.findOne({ textoRespuesta: this.finalQuestion.incorrect2 }) .then(respuestaExistente => { if (!respuestaExistente) { // Si no existe ya esa pregunta la crea var nuevaRespuesta = new Respuesta({ - textoRespuesta: this.finalQuestion.question, + textoRespuesta: this.finalQuestion.incorrect2, tipos: [idTipo] }); @@ -148,14 +166,13 @@ class GuardarBaseDatos{ } guardarTerceraIncorrecta(idTipo){ - console.log("Guardando tercera incorrecta"); //comprobar si la tercera respuesta existe ya en la base de datos Respuesta.findOne({ textoRespuesta: this.finalQuestion.incorrect3 }) .then(respuestaExistente => { if (!respuestaExistente) { // Si no existe ya esa pregunta la crea var nuevaRespuesta = new Respuesta({ - textoRespuesta: this.finalQuestion.question, + textoRespuesta: this.finalQuestion.incorrect3, tipos: [idTipo] }); diff --git a/questionsService/obtenerPreguntasBaseDatos.js b/questionsService/obtenerPreguntasBaseDatos.js index 9e6b269b..a5416bda 100644 --- a/questionsService/obtenerPreguntasBaseDatos.js +++ b/questionsService/obtenerPreguntasBaseDatos.js @@ -1,22 +1,30 @@ +const mongoose = require('mongoose'); + +const Categoria = mongoose.model('Categoria'); +const Pregunta = mongoose.model('Pregunta'); +const Tipos = mongoose.model('Tipos'); +const Respuesta = mongoose.model('Respuesta'); + class ObtenerPreguntas{ - obtenerPregunta(){ - var pregunta; - var respuestaCorrecta; - var respuestaIncorrecta1; - var respuestaIncorrecta2; - var respuestaIncorrecta3; + obtenerPregunta(){ + console.log("Obteniendo pregunta"); + var pregunta; + var respuestaCorrecta; + var respuestaIncorrecta1; + var respuestaIncorrecta2; + var respuestaIncorrecta3; - Pregunta.aggregate([ + Pregunta.aggregate([ { $sample: { size: 1 } } ]).then(pregunta => { var pregunta_id = pregunta._id; pregunta = pregunta.textoPregunta; - Tipo.findOne({ _id: { $in: pregunta.pregunta_id } }).then(tipo => { - console.log(tipo_id); - respuestaCorrecta = pregunta.respuestaCorrecta; - console.log(respuestaCorrecta); - Respuesta.aggregate([ + Tipos.findOne({ _id: { $in: pregunta.pregunta_id } }).then(tipo => { + console.log(tipo_id); + respuestaCorrecta = pregunta.respuestaCorrecta; + console.log(respuestaCorrecta); + Respuesta.aggregate([ { $match: { nombreTipo: tipo._id, texto: { $ne: [respuestaCorrecta, "Ninguna de las anteriores" ]} } }, { $sample: { size: 3 } } @@ -35,6 +43,12 @@ class ObtenerPreguntas{ console.error(err); }); + console.log(pregunta); + console.log(respuestaCorrecta); + console.log(respuestaIncorrecta1); + console.log(respuestaIncorrecta2); + console.log(respuestaIncorrecta3); + return resultado = { pregunta: pregunta.textoPregunta, correcta: respuestaCorrecta, diff --git a/questionsService/obtenerPreguntasWikidata.js b/questionsService/obtenerPreguntasWikidata.js index 752b82ab..583ddf11 100644 --- a/questionsService/obtenerPreguntasWikidata.js +++ b/questionsService/obtenerPreguntasWikidata.js @@ -29,40 +29,44 @@ class ObtenerPreguntaWikiData { Se obtiene la consulta y la información que necesitamos para posteriores métodos */ leerYSacarConsultas() { - // Leer el archivo XML - fs.readFile('preguntas.xml', 'utf-8', (err, data) => { - - if (err) { - console.error('Error al leer el archivo:', err); - return; - } - - // Parsear el XML - xml2js.parseString(data, (parseErr, result) => { - if (parseErr) { - console.error('Error al analizar el XML:', parseErr); + return new Promise((resolve, reject) => { + // Leer el archivo XML + fs.readFile('preguntas.xml', 'utf-8', (err, data) => { + + if (err) { + console.error('Error al leer el archivo:', err); return; } - // Obtener las preguntas disponibles - var preguntas = result.preguntas.pregunta; - - // Seleccionar una pregunta aleatoria - var pregunta = preguntas[Math.floor(Math.random() * preguntas.length)]; - - // Obtener la información relativa a la pregunta - this.question = pregunta.$.question; - this.type = pregunta.$.type; - this.category = pregunta.$.category; - - // Obtener la consulta - var query = pregunta.query[0]; - var consultaParte = query.match(/SELECT(.*?)WHERE/s)[1].trim(); - - // Dividir la parte de la consulta por los símbolos '?' para obtener las labels - this.labels = consultaParte.split('?').map(part => part.trim()).filter(part => part !== ''); - - //obtenemos todas las entradas de wikidata para esa query - this.obtenerEntidadesConsulta(query); + + // Parsear el XML + xml2js.parseString(data, (parseErr, result) => { + if (parseErr) { + console.error('Error al analizar el XML:', parseErr); + return; + } + // Obtener las preguntas disponibles + var preguntas = result.preguntas.pregunta; + + // Seleccionar una pregunta aleatoria + var pregunta = preguntas[Math.floor(Math.random() * preguntas.length)]; + + // Obtener la información relativa a la pregunta + this.question = pregunta.$.question; + this.type = pregunta.$.type; + this.category = pregunta.$.category; + + // Obtener la consulta + var query = pregunta.query[0]; + var consultaParte = query.match(/SELECT(.*?)WHERE/s)[1].trim(); + + // Dividir la parte de la consulta por los símbolos '?' para obtener las labels + this.labels = consultaParte.split('?').map(part => part.trim()).filter(part => part !== ''); + + //obtenemos todas las entradas de wikidata para esa query + this.obtenerEntidadesConsulta(query) + .then(() => resolve()) + .catch(error => reject(error)); + }); }); }); } @@ -71,20 +75,24 @@ class ObtenerPreguntaWikiData { Hace una llamada a la API para poder obtener la información relativa a la consulta Si la llamada tiene exito se llama a otro metodo para procesar la información */ - obtenerEntidadesConsulta(consulta){ - const apiUrl = 'https://query.wikidata.org/sparql'; - - axios.get(apiUrl, { - params: { - query: consulta, - format: 'json' - } - }) - .then(response => { - this.obtenerInformacionParaPregunta(response.data); - }) - .catch(error => { - console.error('Error:', error); + obtenerEntidadesConsulta(consulta){ + return new Promise((resolve, reject) => { + const apiUrl = 'https://query.wikidata.org/sparql'; + + axios.get(apiUrl, { + params: { + query: consulta, + format: 'json' + } + }) + .then(response => { + this.obtenerInformacionParaPregunta(response.data) + .then(() => resolve()) + .catch(error => reject(error)); + }) + .catch(error => { + console.error('Error:', error); + }); }); } @@ -92,31 +100,35 @@ class ObtenerPreguntaWikiData { Obtenemos 4 entidades aleatorias de los datos devueltos por la consulta que hemos realizado */ obtenerInformacionParaPregunta(data){ - //obtenemos el label y el resultado de todas las entidades - if(data && data.results && data.results.bindings.length > 0){ - var entidades = data.results.bindings.map(binding => { - return { - //obtenemos el label de la "pregunta" (ejemplo country) - label: this.obtenerValorPropiedad(binding, this.labels[1]), - //obtenemos el label de la "respuesta" (ejemplo capital) - result: this.obtenerValorPropiedad(binding, this.labels[2]) - }; - }); + return new Promise((resolve, reject) => { + //obtenemos el label y el resultado de todas las entidades + if(data && data.results && data.results.bindings.length > 0){ + var entidades = data.results.bindings.map(binding => { + return { + //obtenemos el label de la "pregunta" (ejemplo country) + label: this.obtenerValorPropiedad(binding, this.labels[1]), + //obtenemos el label de la "respuesta" (ejemplo capital) + result: this.obtenerValorPropiedad(binding, this.labels[2]) + }; + }); - //obtenemos 4 índices aleatorios únicos - var indicesAleatorios = []; - while(indicesAleatorios.length < 4){ - var indiceAleatorio = Math.floor(Math.random() * entidades.length); - if(!indicesAleatorios.includes(indiceAleatorio)){ - indicesAleatorios.push(indiceAleatorio); + //obtenemos 4 índices aleatorios únicos + var indicesAleatorios = []; + while(indicesAleatorios.length < 4){ + var indiceAleatorio = Math.floor(Math.random() * entidades.length); + if(!indicesAleatorios.includes(indiceAleatorio)){ + indicesAleatorios.push(indiceAleatorio); + } } - } - //obtenemos las 4 entidades aleatorias que vamos a utilizar para generar la pregunta - this.answers = indicesAleatorios.map(indice => entidades[indice]); + //obtenemos las 4 entidades aleatorias que vamos a utilizar para generar la pregunta + this.answers = indicesAleatorios.map(indice => entidades[indice]); - this.generarTextoPregunta(); - } + this.generarTextoPregunta() + .then(() => resolve()) + .catch(error => reject(error)); + } + }); } /* @@ -135,38 +147,42 @@ class ObtenerPreguntaWikiData { generamos la pregunta con la información que hemos obtenido */ generarTextoPregunta(){ - //leemos el archivo - fs.readFile('esqueletoPreguntas.xml', 'utf-8', (err, data) => { - if (err) { - console.error('Error al leer el esqueleto de las preguntas:', err); - return; - } - - //parseamos el xml - xml2js.parseString(data, (parseErr, result) => { - if (parseErr) { - console.error('Error al analizar el esqueleto de las preguntas:', parseErr); - return; - } + return new Promise((resolve, reject) => { + //leemos el archivo + fs.readFile('esqueletoPreguntas.xml', 'utf-8', (err, data) => { + if (err) { + console.error('Error al leer el esqueleto de las preguntas:', err); + return; + } - //obtenemos el esqueleto de la pregunta que queremos hacer - var textoPregunta = this.obtenerTextoPregunta(result, this.question, this.type); - - //comprobamos que el resultado es valido para hacer la pregunta (que no sea QXXXXX) - var preguntaCorrecta = this.answers.find(entidad => { - return entidad.label !== "Ninguna de las anteriores"; + //parseamos el xml + xml2js.parseString(data, (parseErr, result) => { + if (parseErr) { + console.error('Error al analizar el esqueleto de las preguntas:', parseErr); + return; + } + + //obtenemos el esqueleto de la pregunta que queremos hacer + var textoPregunta = this.obtenerTextoPregunta(result, this.question, this.type); + + //comprobamos que el resultado es valido para hacer la pregunta (que no sea QXXXXX) + var preguntaCorrecta = this.answers.find(entidad => { + return entidad.label !== "Ninguna de las anteriores"; + }); + + if(preguntaCorrecta){ + //rellenamos el esqueleto de la pregunta con los datos de la entidad + var pregunta = preguntaCorrecta.label; + var respuestaCorrecta = preguntaCorrecta.result; + var consulta = textoPregunta.replace('{RELLENAR}', pregunta); + + this.generarPregunta(consulta, respuestaCorrecta) + .then(() => resolve()) + .catch(error => reject(error)); + } }); - - if(preguntaCorrecta){ - //rellenamos el esqueleto de la pregunta con los datos de la entidad - var pregunta = preguntaCorrecta.label; - var respuestaCorrecta = preguntaCorrecta.result; - var consulta = textoPregunta.replace('{RELLENAR}', pregunta); - - this.generarPregunta(consulta, respuestaCorrecta); - } }); - }); + }); } /* @@ -186,24 +202,30 @@ class ObtenerPreguntaWikiData { generamos un json con la info necesaria de la pregunta para poder guardarla en la base de datos */ generarPregunta(consulta, respuestaCorrecta){ - var respuestasIncorrectas = []; - var num = 0; - //añadimos el resto de respuestas - for(var i = 0; i < this.answers.length; i++){ - if(this.answers[i].result !== respuestaCorrecta){ - respuestasIncorrectas[num] = this.answers[i].label; - num++; + return new Promise((resolve, reject) => { + var respuestasIncorrectas = []; + var num = 0; + //añadimos el resto de respuestas + for(var i = 0; i < this.answers.length; i++){ + if(this.answers[i].result !== respuestaCorrecta){ + respuestasIncorrectas[num] = this.answers[i].label; + num++; + } } - } - //guardamos la pregunta para añadirla a la base de datos - this.finalQuestion = { - question: consulta.trim().replace(/\r?\n|\r/g, ''), - correct: respuestaCorrecta, - incorrect1: respuestasIncorrectas[0], - incorrect2: respuestasIncorrectas[1], - incorrect3: respuestasIncorrectas[2] - } + //guardamos la pregunta para añadirla a la base de datos + this.finalQuestion = { + question: consulta.trim().replace(/\r?\n|\r/g, ''), + correct: respuestaCorrecta, + incorrect1: respuestasIncorrectas[0], + incorrect2: respuestasIncorrectas[1], + incorrect3: respuestasIncorrectas[2], + category: this.category, + type: this.type + } + + resolve(); + }); } obtenerPregunta(){ diff --git a/questionsService/question-model.js b/questionsService/question-model.js index 29f7560d..91aec689 100644 --- a/questionsService/question-model.js +++ b/questionsService/question-model.js @@ -2,7 +2,6 @@ const mongoose = require('mongoose'); //preguntas const preguntaSchema = new mongoose.Schema({ - _id: mongoose.Schema.Types.ObjectId, textoPregunta: { type: String, required: true @@ -21,7 +20,6 @@ const Pregunta = mongoose.model('Pregunta', preguntaSchema); //categoria const categoriaSchema = new mongoose.Schema({ - _id: mongoose.Schema.Types.ObjectId, nombre: { type: String, required: true @@ -32,7 +30,6 @@ const Categoria = mongoose.model('Categoria', categoriaSchema); //Respuesta const respuestaSchema = new mongoose.Schema({ - _id: mongoose.Schema.Types.ObjectId, textoRespuesta: { type: String, required: true @@ -46,7 +43,6 @@ const Respuesta = mongoose.model('Respuesta', respuestaSchema); //Tipos const tiposSchema = new mongoose.Schema({ - _id: mongoose.Schema.Types.ObjectId, idPreguntas: [{ type: String, required: true diff --git a/questionsService/question-service.js b/questionsService/question-service.js index d7b82230..d55662f4 100644 --- a/questionsService/question-service.js +++ b/questionsService/question-service.js @@ -4,6 +4,8 @@ const mongoose = require('mongoose'); const xml2js = require('xml2js'); const fs = require('fs'); +const Model = require('./question-model') + const Question = require("./obtenerPreguntasBaseDatos"); const question = new Question(); @@ -20,11 +22,10 @@ app.use(express.json()); const mongoUri = process.env.MONGODB_URI || 'mongodb://localhost:27017/questionsdb'; mongoose.connect(mongoUri); -const instancia = newquestion.ejecutarOperaciones(); - app.get('/getQuestion', async(req,res)=> { try{ //coger pregunta bd + console.log("LLegamos al question service") const questions = await question.obtenerPregunta(); //para devolver la pregunta res.json(questions); @@ -37,9 +38,7 @@ app.get('/getQuestion', async(req,res)=> { app.get('/generateQuestions', async(req,res)=> { try{ - console.log("Generando preguntas en el question-service"); const instancia = newquestion.ejecutarOperaciones(); - console.log(`Ejecutado correctamente`); } catch(error) { res.status(error.response.status).json({ error: error.response.data.error }); diff --git a/questionsService/questionGeneration.js b/questionsService/questionGeneration.js index 916c3ced..4a99cb22 100644 --- a/questionsService/questionGeneration.js +++ b/questionsService/questionGeneration.js @@ -6,10 +6,9 @@ const guardarPregunta = new GuardarPregunta(); class GenerarPregunta { // Método para ejecutar las operaciones - ejecutarOperaciones() { - console.log(`Ejecutando operaciones`); - preguntaWiki.leerYSacarConsultas(); - //guardarPregunta.guardarEnBaseDatos(preguntaWiki.obtenerPregunta()); + async ejecutarOperaciones() { + await preguntaWiki.leerYSacarConsultas(); + guardarPregunta.guardarEnBaseDatos(preguntaWiki.obtenerPregunta()); } }