Así que estoy usando mongoose y MongoDB para crear un chatbot, y quiero poder ver si alguno de los documentos coincide con alguna parte de lo que dijo el usuario sin que tenga que ser una coincidencia exacta. Sé que si la cadena de entrada fuera solo una parte del elemento, podría usar el operador $regex, pero en mi caso, el elemento es solo una parte de la cadena de entrada. Esto es lo que tengo hasta ahora:
app.post('/mood',(req,res) => { const str = req.body.mood.toLowerCase(); var arr = str.split(/([_\W])/); console.log(arr); Words.findOne({words: {$in: arr}},(err,data) => { if (err) { res.json({ status: 'failure', reason: 'Server error.', prompt: null }); console.log(err); return; } if (!data || data==null || data==[]) { res.json({ status: 'failure', reason: 'We don\'t have a response to that yet. Would you like to make one?', prompt: 'make' }); return; } console.log(data.words); var reply = data.responses[Math.floor(Math.random()*data.responses.length)].phrase; res.json({ status: 'success', reply}); }); });pero eso solo funciona para campos de una sola palabra como "hola", no para frases como "cómo estás" o "mi nombre es". Así que si alguien dice "¿cómo estás?" no aparecerá "cómo estás" si uso la cadena completa O si la divido en "cómo", "estás", "tú", "haciendo" y "?". ¿Cómo hago para ver si toda la cadena de la base de datos coincide con alguna parte de la cadena del usuario?
Puedes construir una expresión regular a partir de la cadena:
const str = req.body.mood.toLowerCase(); let regex = new RegExp(str.split(/[_\W+]/).filter(str => { return /^[\w]+$/.test(str) }).join('|')) console.log(regex.toString()); La expresión regular para la cadena "how are you doing?" será /how|are|you|doing/ . No tenemos que preocuparnos por los caracteres de escape al crear la expresión regular, ya que solo tenemos caracteres alfa.
Ahora puede usar esa expresión regular en su consulta para encontrar las palabras proporcionadas por el usuario en todos sus campos de words :
Words.findOne({words: {$regex: regex}}, ...