Práctica recomendada: búsqueda de texto en Ruby, ¿o dejar que MongoDB haga el trabajo?

Tengo una serie de palabras clave, que pueden tener una longitud variable. Para este ejemplo imagina que hay 50:

keywords = ['dog','cat','monkey'...'bird']

Tengo una serie de oraciones (nuevamente de longitud variable) que quiero recorrer, buscando cada una de las palabras clave.

sentences = [ ['My dog ate cat food'], ['I went to the store.'], ... ]

Si la oración contiene alguna de las palabras clave, la muevo a una nueva matriz "coincidente". Entonces, en Ruby, mi código se ve así:

sentences.each do |sentence|
  keywords.each do |keyword|
    if sentence.match(/\b#{keyword}\b/i)
      matched << sentence
    end
  end
end

Esto lleva bastante tiempo y parece realmente ineficiente, especialmente si tengo una gran lista de palabras clave y una gran lista de oraciones. Soy el primero en admitir que mi desarrollo de Ruby aún no es tan bueno. ¿Existe una manera más fácil y eficiente de hacerlo?

Estoy usando MongoDB para almacenar las palabras clave y las oraciones. Si hay un método mejor usando la base de datos, me encantaría explorarlo.

preguntado el 03 de mayo de 12 a las 20:05

¿Está buscando coincidencias literales o búsqueda de texto completo? -

Solo una coincidencia literal. "gato" en lugar de "catatónico" o "lolcat". -

1 Respuestas

No he usado MonogDB antes, pero puedes optimizar un poco tu código Ruby. Ya que solo te importa si hay una coincidencia de cualquier palabra clave en la oración, empujaría la lógica al motor Ruby regexp:

regexp = keywords.map { |keyword| Regexp.quote(keyword) }.join('|')

matched = sentences.select do |sentence|
  sentence[0].match(/\\b(?:#{regexp})\\b/i)
end

Lo que hace es crear una expresión regular que combina todas sus palabras clave. De esa manera, solo recorre las oraciones en lugar de cada palabra clave.

contestado el 03 de mayo de 12 a las 21:05

Eso funcionó muy bien, tuve que hacer un par de pequeños cambios, pero creo que esto es mucho mejor. ¡Gracias! Terminé con: matched = sentences.select do |sentence| sentence[0].match(/\b(?:#{regexp})\b/i) end - jbnunn

¡Excelente! Acepte la respuesta para que otros también puedan encontrarla. ¡Mucha suerte con tu desarrollo futuro! :) - rjk

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.