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

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

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

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

Есть другие идеи?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
5
0
6 371
7

Ответы 7

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

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

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

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

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

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

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

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

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

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

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

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

И "издатель: Nature * страницы> 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);
}

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

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

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

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

Очень интересно. Похоже на IBatis без маппинга и XML

Camilo Díaz Repka 02.10.2008 07:40

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

String [] массив;

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

}

Это не совсем ответ на вопрос.

user806549 27.09.2013 17:02

Другие вопросы по теме