Разбор поисковых запросов в Java - PullRequest
5 голосов
/ 17 августа 2008

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

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

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

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

Ответы [ 7 ]

3 голосов
/ 01 октября 2008

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

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

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

1 голос
/ 30 сентября 2008

Вы можете попробовать использовать что-то вроде javacc (компилятор Java) для реализации синтаксического анализатора или просто вручную проанализировать строку методом грубой силы Каждый раз, когда вы сталкиваетесь с выражением, вы представляете его как объект. Тогда вам просто нужно перевести ваше дерево выражений в предложение 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 голос
/ 17 августа 2008

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

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

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

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

0 голосов
/ 27 сентября 2013

массив String [];

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

}
0 голосов
/ 18 августа 2009

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

0 голосов
/ 17 августа 2008

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...