2012-04-07 12 views
13

Estoy buscando una biblioteca Java/Scala que pueda tomar una consulta del usuario y un texto, y devuelve si hubo una coincidencia o no.¿Cómo hacer la coincidencia de cadenas de Java utilizando la sintaxis de búsqueda booleana?

Estoy procesando un flujo de información, es decir, Twitter Stream, y no puedo permitir el uso de un proceso por lotes, necesito evaluar cada tweet en tiempo real, en lugar de indexarlo a través de Lucene RAMDisk y consultarlo más tarde.

Es posible crear un analizador/lexer usando ANTLR, pero este es un uso tan común que no puedo creer que nadie haya creado una lib anteriormente.

Algunas muestras de TextQuery Ruby library que hace exactamente lo que necesitan:

TextQuery.new("'to be' OR NOT 'to_be'").match?("to be") # => true 

    TextQuery.new("-test").match?("some string of text")  # => true 
    TextQuery.new("NOT test").match?("some string of text") # => true 

    TextQuery.new("a AND b").match?("b a")     # => true 
    TextQuery.new("a AND b").match?("a c")     # => false 

    q = TextQuery.new("a AND (b AND NOT (c OR d))") 
    q.match?("d a b")           # => false 
    q.match?("b")            # => false 
    q.match?("a b cdefg")          # => true 

    TextQuery.new("a~").match?("adf")       # => true 
    TextQuery.new("~a").match?("dfa")       # => true 
    TextQuery.new("~a~").match?("daf")      # => true 
    TextQuery.new("2~a~1").match?("edaf")      # => true 
    TextQuery.new("2~a~2").match?("edaf")      # => false 

    TextQuery.new("a", :ignorecase => true).match?("A b cD") # => true 

Una vez que se implementó en Ruby no es adecuado para mi plataforma, también no puedo usar JRuby sólo para este punto de nuestra solución:

me encontré con una pregunta similar pero no pudo obtener respuesta de ella: Boolean Query/Expression to a Concrete syntax tree

Gracias!

+0

@edgarespina me acaba de decir acerca de [Parboiled] (https://github.com/sirthias/parboiled/) parece muy similar con Treetop para Ruby. Tal vez esa es la solución más fácil. – arjones

Respuesta

3

Dado que está haciendo búsqueda de texto, trataría de aprovechar parte de la infraestructura proporcionada por Lucene. Puede ser que pueda crear un QueryParser y llamar al parse para obtener un Query. subclases instanciables de consulta son:

TermQuery 
MultiTermQuery 
BooleanQuery 
WildcardQuery 
PhraseQuery 
PrefixQuery 
MultiPhraseQuery 
FuzzyQuery 
TermRangeQuery 
NumericRangeQuery 
SpanQuery 

entonces usted puede ser capaz de utilizar la coincidencia de patrones para poner en práctica lo que significa apropiado para su aplicación:

def match_?(tweet: String, query: Query): Boolean = query match { 
    case q: TermQuery => tweet.contains(q.getTerm.text) 
    case q: BooleanQuery => 
    // return true if all must clauses are satisfied 
    // call match_? recursively 
    // you need to cover all subclasses above 
    case _ => false 
} 

val q = queryParser.parse(userQuery) 
val res = match_?(tweet, q) 

Aquí es an implementation. Seguramente tiene errores pero obtendrá la idea y muestra una prueba de concepto que funciona. Reutiliza la sintaxis, la documentación y la gramática del Lucene QueryParser predeterminado.

3

Spring Expression Language (SpEL) admite un operador matches que devuelve boolean s en expresiones regulares. Consulte la sección this de la documentación para conocer su uso.

Esto también le permitiría utilizar operadores lógicos como and, or y not.

Cuestiones relacionadas