Как выполнить сопоставление строк Java с помощью булевого синтаксиса поиска?
Я ищу библиотеку Java/ Scala, которая может принимать пользовательский запрос и текст и возвращает, если есть соответствие или нет.
Я обрабатываю поток информации, т.е. Twitter Stream, и не могу позволить использовать процесс пакетной обработки, мне нужно оценить каждый твит в реальном времени, вместо того, чтобы индексировать его через Lucene RAMDisk и запрашивать его позже.
Возможно создать парсер/лексер, используя ANTLR, но это такое обычное использование, что я не могу поверить, что никто не создает lib раньше.
Некоторые примеры из TextQuery Ruby library, который делает именно то, что мне нужно:
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
Как только он был реализован в Ruby, он не подходит для моей платформы, также я не могу использовать JRuby именно для этого момента в нашем решении:
Я нашел аналогичный вопрос, но не смог получить ответ от него:
Boolean Query/Expression для дерева синтаксиса Concrete
Спасибо!
Ответы
Ответ 1
Учитывая, что вы выполняете текстовый поиск, я попытаюсь использовать некоторую инфраструктуру, предоставленную Lucene. Возможно, вы могли бы создать QueryParser
и вызвать parse
, чтобы вернуть Query
. Моментальные подклассы Query:
TermQuery
MultiTermQuery
BooleanQuery
WildcardQuery
PhraseQuery
PrefixQuery
MultiPhraseQuery
FuzzyQuery
TermRangeQuery
NumericRangeQuery
SpanQuery
Затем вы можете использовать сопоставление шаблонов для реализации того, что означает соответствие для вашего приложения:
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)
Вот реализация. У него наверняка есть ошибки, но вы получите эту идею, и это показывает действующее доказательство концепции. Он повторно использует синтаксис, документацию и грамматик по умолчанию Lucene QueryParser.
Ответ 2
Spring Язык выражения (SpEL) поддерживает оператор matches
, который возвращает boolean
на основе регулярных выражений. См. этот раздел документации для использования.
Это также позволит вам использовать логические операторы, такие как and
, or
и not
.