2012-04-07 13 views
13

Ich bin auf der Suche nach einer Java/Scala-Bibliothek, die eine Benutzerabfrage und einen Text nehmen und zurückgeben kann, wenn es eine Übereinstimmung gab oder nicht.Wie funktioniert die Java String-Übereinstimmung mit der booleschen Suchsyntax?

Ich verarbeite einen Strom von Informationen, zB: Twitter Stream, und kann es mir nicht leisten, einen Batch-Prozess zu verwenden, muss ich jeden Tweet in Echtzeit bewerten, anstatt es durch Lucene RAMDisk indizieren und später abfragen.

Es ist möglich, einen Parser/Lexer mit ANTLR zu erstellen, aber das ist so gebräuchlich, dass ich nicht glauben kann, dass niemand zuvor eine Lib erstellt hat.

Einige Proben von TextQuery Ruby library das genau das tut, was ich brauche:

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 

Sobald es in Ruby implementiert wurde für meine Plattform ist es nicht geeignet, auch JRuby Ich kann nicht nur für diesen Punkt auf unserer Lösung verwenden:

fand ich eine ähnliche Frage, aber nicht Antwort von ihm bekommen konnte: Boolean Query/Expression to a Concrete syntax tree

Dank!

+0

@edgarespina gerade erzählte mir über [Parboiled] (https://github.com/sirthias/parboiled/) es scheint sehr ähnlich mit Treetop für Ruby. Vielleicht ist das die einfachste Lösung. – arjones

Antwort

3

Da Sie eine Textsuche durchführen, würde ich versuchen, einen Teil der von Lucene bereitgestellten Infrastruktur zu nutzen. Möglicherweise können Sie eine QueryParser erstellen und parse anrufen, um eine Query zurück zu bekommen. Instanziierbare Subklassen von Abfrage sind:

TermQuery 
MultiTermQuery 
BooleanQuery 
WildcardQuery 
PhraseQuery 
PrefixQuery 
MultiPhraseQuery 
FuzzyQuery 
TermRangeQuery 
NumericRangeQuery 
SpanQuery 

Dann können Sie in der Lage sein, Pattern-Matching zu verwenden, um das umzusetzen, was eine Übereinstimmung für Ihre Anwendung bedeutet:

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) 

Hier an implementation ist. Es hat sicherlich Bugs, aber Sie werden die Idee bekommen und es zeigt einen funktionierenden Proof of Concept. Es verwendet die Syntax, Dokumentation und Grammatik des standardmäßigen Lucene QueryParser.

3

Spring Ausdruck Sprache (SpEL) unterstützt einen matches Operator, der boolean s basierend auf regulären Ausdrücken zurückgibt. Siehe Abschnitt this Abschnitt der Dokumentation für die Verwendung.

Damit können Sie auch logische Operatoren wie and, or und not verwenden.

Verwandte Themen