Разбор поисковых запросов в Java

Я пытался найти простой способ разобрать поисковый запрос и преобразовать его в SQL-запрос для моей БД.

Я нашел два решения:

  1. Lucene : мощный поисковый движок на основе Java, содержит анализатор запросов, но он не очень настраиваемый, и я мог бы найти способ легко взломать / адаптировать его для создания запросов SQL.
  2. ANTLR : ветеран текстового лексера-парсера. Используется для создания чего угодно, от компиляторов до небоскребов. ANTLR легко настраивается, но теперь всем, кто касается кода, придется изучать новый язык ...

Есть еще идеи?

17.08.2008 19:21:26
7 ОТВЕТОВ

Многое зависит от того, какие запросы нужно анализировать, и от структуры данных в вашей базе данных. Я собираюсь предположить, что вы не пытаетесь выполнить полнотекстовый поиск в БД (то есть в поисковой системе по всей вашей БД), потому что, как скажут вам большинство специалистов по поиску информации, производительность для этого ужасна. Инвертированные индексы, безусловно, лучший способ сделать это.

Расскажите нам немного больше о фактической проблеме: что собираются вводить пользователи, чего они ожидают в качестве вывода и какова модель данных. Разработайте поисковое решение без этих частей информации, и вы получите далеко не оптимальный результат.

0
17.08.2008 19:28:04

Что именно ты имеешь в виду? Я использовал Lucene для поиска по тексту, но он отличается тем, что строит индекс и ищет его вместо того , чтобы обращаться к базе данных вообще.

Недавно я настроил систему, в которой я индексирую таблицу в Lucene, объединяя все столбцы (разделенные пробелами) в одно поле, вставляя это в Lucene, а затем добавляя первичный ключ в отдельный столбец. Lucene выполняет весь поиск и возвращает список первичных ключей, которые я использовал, чтобы получить заполненный набор результатов и отобразить его пользователю.

Преобразование поискового запроса в оператор SQL показалось бы мне немного беспорядочным.

Кроме того, вот отличный учебник для начинающих, объясняющий основную структуру Lucene .

1
17.08.2008 19:30:37

Вы правильно предполагаете, что я не ищу полнотекстовый поиск. Информация выглядит примерно так, как эта схема для информации о книге: Имя: строка, издатель: строка, num_pages int, publish_date: date ...

Поисковые запросы имеют вид:

  1. Гарри Поттер (ищите любые книги, в имени которых есть и Гарри, и Поттер)
  2. издатель: Nature * pages> 100 (книги от издателя, начиная с Nature с более чем 100 книгами)
  3. («Новый год» или Рождество) и подарок (вы получите картину ...)
  4. физика и публикации> 01.01.2008 (новые книги по физике)
0
17.08.2008 19:37:41

Вы можете попробовать использовать что-то вроде javacc (Java Compiler Compiler) для реализации синтаксического анализатора или просто вручную проанализировать строку с помощью грубой силы. Каждый раз, когда вы сталкиваетесь с выражением, вы представляете его как объект. Тогда вам просто нужно перевести ваше дерево выражений в предложение where.

Например: «Гарри Поттер» становится

new AndExp(new FieldContainsExp("NAME", "Harry"), new FieldContainsExp("NAME", "Potter")

И "издатель: Природа * страниц> 100" становится

new AndExp(new FieldContainsExp("PUBLISHER", "Nature"), FieldGreaterThan("PAGES", 100))

Затем, когда они у вас есть, их довольно легко превратить в SQL:

FieldContainsExp.toSQL(StringBuffer sql, Collection<Object> args) {
  sql.append(fieldName);
  sql.append(" like ");
  sql.append("'%?%'");
  args.add(value);
}

AndExp.toSQL(StringBuffer sql, Collection<Object> args) {
    exp1.toSQL(sql, args);
    sql.append(" AND ");
    exp2.toSQL(sql, args);
}

Вы можете представить себе остальное. Вы можете вкладывать и выражения так глубоко, как вы хотите.

1
26.11.2013 04:27:01

SQL-ORM - это очень легкая библиотека Java, которая включает возможность построения (динамического) запроса SQL в Java в виде графа объектов.

ИМХО, это гораздо лучший метод для построения динамических запросов SQL, чем обычный метод конкатенации строк.

Отказ от ответственности: я внес очень незначительный вклад в этот проект

3
30.09.2008 20:09:50
Очень интересно. Похоже, IBatis без карт и XML-материалов
Camilo Díaz Repka 2.10.2008 03:40:27

Попробуйте объединить инструмент ORM (например, openJPA) и Compass (фреймворк для OSEM). Он автоматически индексирует обновления, выполненные с помощью инструментов ORM, и дает вам возможность Lucene для поиска. После этого вы, конечно, можете получить объект из БД. Он превосходит любое поисковое решение на основе SQL.

0
18.08.2009 17:50:11

Массив String [];

int checkWord(String searchWord)
{
    for(int i = 0; i < array.length; i++)
    {
        if(searchWord.equals(array[i]))
            return i;
    }
    return 0;

}
-2
27.09.2013 12:45:08
Это на самом деле не отвечает на вопрос.
user806549 27.09.2013 13:02:22