1 Обзор
В этой статье мы рассмотримApache SolrОсновные понятия поисковых систем — полнотекстовый поиск.
Apache Solr — это платформа с открытым исходным кодом, предназначенная для обработки миллионов документов. Мы сделаем это с помощью библиотеки Java —SolrJпример, чтобы представить его основные функции.
2. Конфигурация Maven
Так как Solr с открытым исходным кодом — мы можем просто скачать бинарник и запустить сервер отдельно в нашем приложении.
Для связи с сервером мы определим зависимости Maven для клиента SolrJ:
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>6.4.2</version>
</dependency>
ты будешьздесьНайдите последние зависимости.
3. Индексные данные
Для того, чтобы индексировать и поискать данные, нам нужно создатьcore
иitem
индексировать данные.
Прежде чем мы сможем это сделать, нам нужно проиндексировать данные на сервере, чтобы их можно было искать.
Мы можем индексировать данные разными способами. Мы можем импортировать данные непосредственно из реляционных баз данных с помощью обработчиков импорта данных, загружать данные через Solr Cell с помощью Apache Tika или загружать данные XML/XSLT, JSON и CSV с помощью обработчиков индексов.
3.1 Индексирование документов Solr
Мы можем индексировать данные в ядре, создав SolrInputDocument. Во-первых, нам нужно заполнить документ нашими данными, а затем просто вызвать SolrJ API для индексации документа:
SolrInputDocument doc = new SolrInputDocument();
doc.addField("id", id);
doc.addField("description", description);
doc.addField("category", category);
doc.addField("price", price);
solrClient.add(doc);
solrClient.commit();
Обратите внимание, что идентификатор должен быть уникальным для разных элементов. Индексированный документ обновляет документ на основе идентификатора.
3.2 Индексные компоненты
SolrJ предоставляет API для индексации Java-бинов. Чтобы проиндексировать bean-компонент, нам нужно аннотировать его с помощью @Field:
public class Item {
@Field
private String id;
@Field
private String description;
@Field
private String category;
@Field
private float price;
}
Как только мы добавим bean-компонент, индекс уже установлен:
solrClient.addBean(item);
solrClient.commit();
4. Солер-запрос
Поиск — самая мощная функция Solr. Когда мы индексируем документы в репозитории, мы можем выполнять поиск по ключевым словам, фразам, диапазонам дат и т. д. Результаты сортируются по релевантности (оценке).
4.1 Основной запрос
Сервер предоставляет API для операций поиска. Мы можем вызвать программу /select или /query для обработки запроса.
Выполним простой поиск:
SolrQuery query = new SolrQuery();
query.setQuery("brand1");
query.setStart(0);
query.setRows(10);
QueryResponse response = solrClient.query(query);
List<Item> items = response.getBeans(Item.class);
SolrJ будет использовать основной параметр запроса q внутри своего запроса к серверу. Количество возвращаемых записей равно 10. Если параметры start и rows не указаны, индекс начинается с 0.
Приведенный выше поисковый запрос найдет любой документ, содержащий полное слово «brand1» в любом из проиндексированных полей. Обратите внимание, что простой поиск не чувствителен к регистру.
Давайте посмотрим на другой пример. Мы хотим найти любое слово, содержащее «ранд», которое начинается с любого количества символов и заканчивается только одним символом. Мы можем использовать * и ? в запросе Подстановочный знак:
query.setQuery("*rand?");
Запросы Solr также поддерживают логические операции, как в SQL:
query.setQuery("brand1 AND (Washing OR Refrigerator)");
Все логические операторы должны быть в верхнем регистре; анализатор запросов поддерживает И, ИЛИ, НЕ, + и -.
Что еще более важно, если мы хотим выполнять поиск по определенным полям, а не по всем проиндексированным полям, мы можем указать эти поля в запросе:
query.setQuery("description:Brand* AND category:*Washing*");
4.2 Фразовый запрос
До сих пор мы использовали код только для поиска ключевых слов в проиндексированных полях. Мы также можем выполнять поиск по фразам в проиндексированных полях:
query.setQuery("Washing Machine");
Когда у нас есть такая фраза, как «Стиральная машина», стандартный анализатор запросов Solr анализирует ее как «Стиральная машина ИЛИ машина». Для поиска всей фразы мы можем только добавить выражения в двойные кавычки:
query.setQuery("\"Washing Machine\"");
Мы можем использовать поиск близости, чтобы найти слова на определенном расстоянии. Если мы хотим найти фразы, которые разделены хотя бы двумя словами, мы можем использовать следующий запрос:
query.setQuery("\"Washing equipment\"~2");
4.3 Запрос диапазона
Запрос диапазона позволяет получить документацию между указанными диапазонами. Предположим, мы хотим найти цену от 100 до 300:
query.setQuery("price:[100 TO 300]");
Приведенный выше запрос найдет все элементы с ценой от 100 до 300 включительно. Мы можем использовать «}» и «{» для исключения конечных точек:
query.setQuery("price:{100 TO 300]");
4.4 Фильтрация запросов
Запросы с фильтрами можно использовать для ограничения расширенного набора результатов, которые могут быть возвращены. Фильтрация запроса не влияет на сортировку:
SolrQuery query = new SolrQuery();
query.setQuery("price:[100 TO 300]");
query.addFilterQuery("description:Brand1","category:Home Appliances");
Как правило, фильтрующие запросы содержат общие запросы. Поскольку их часто можно использовать повторно, они кэшируются, чтобы сделать поиск более эффективным.
5. Фасетный поиск
Faceting помогает организовать результаты поиска в групповое количество. Мы можем использовать поля, запросы или диапазоны.
5.1 Полевые аспекты
Например, мы хотим получить агрегированное количество категорий в результатах поиска. Мы можем добавить в запрос поле категории:
query.addFacetField("category");
QueryResponse response = solrClient.query(query);
List<Count> facetResults = response.getFacetField("category").getValues();
facetResults будет содержать счетчики для каждой категории в результатах.
5.2 Запрос аспекта
Аспекты запроса полезны, когда мы хотим вернуть количество подзапросов:
query.addFacetQuery("Washing OR Refrigerator");
query.addFacetQuery("Brand2");
QueryResponse response = solrClient.query(query);
Map<String,Integer> facetQueryMap = response.getFacetQuery();
Таким образом, у facetQueryMap будет количество фасетных запросов.
5.3 Срезы диапазона
Аспект диапазона используется для получения количества диапазонов в результатах поиска. Следующий запрос вернет количество ценовых диапазонов от 100 до 251 с интервалом 25:
query.addNumericRangeFacet("price", 100, 275, 25);
QueryResponse response = solrClient.query(query);
List<RangeFacet> rangeFacets = response.getFacetRanges().get(0).getCounts();
В дополнение к числовым диапазонам Solr поддерживает диапазоны дат, интервальные срезы и сводные срезы.
6. Выделите
Мы можем захотеть выделить ключевые слова в поисковом запросе в результатах поиска. Это очень полезно для лучшего понимания результатов. Давайте проиндексируем некоторые документы и определим ключевые слова для выделения:
itemSearchService.index("hm0001", "Brand1 Washing Machine", "Home Appliances", 100f);
itemSearchService.index("hm0002", "Brand1 Refrigerator", "Home Appliances", 300f);
itemSearchService.index("hm0003", "Brand2 Ceiling Fan", "Home Appliances", 200f);
itemSearchService.index("hm0004", "Brand2 Dishwasher", "Washing equipments", 250f);
SolrQuery query = new SolrQuery();
query.setQuery("Appliances");
query.setHighlight(true);
query.addHighlightField("category");
QueryResponse response = solrClient.query(query);
Map<String, Map<String, List<String>>> hitHighlightedMap = response.getHighlighting();
Map<String, List<String>> highlightedFieldMap = hitHighlightedMap.get("hm0001");
List<String> highlightedList = highlightedFieldMap.get("category");
String highLightedText = highlightedList.get(0);
Мы получаем highLightedText: "Home Appliances
". Обратите внимание, что ключевое слово для поиска "Бытовая техника"отметка. Тег выделения по умолчанию, используемый Solr,
, но мы можем изменить его, установив теги pre и post:
query.setHighlightSimplePre("<strong>");
query.setHighlightSimplePost("</strong>");
7. Поисковые подсказки
Важной функцией, поддерживаемой Solr, являются предложения. Мы можем использовать функцию предложений, если ключевые слова в запросе содержат орфографические ошибки или если мы предлагаем автозаполнение ключевых слов для поиска.
7.1. Проверка орфографии
Стандартный обработчик поиска не включает в себя компонент проверки орфографии, его необходимо настраивать вручную. Есть три способа сделать это. Вы можете найти его в официальномwiki pageПодробности конфигурации можно найти в . В нашем примере мы будем использовать IndexBasedSpellChecker, который использует данные индекса для проверки орфографии ключевых слов.
Давайте найдем ключевые слова с ошибками:
query.setQuery("hme");
query.set("spellcheck", "on");
QueryResponse response = solrClient.query(query);
SpellCheckResponse spellCheckResponse = response.getSpellCheckResponse();
Suggestion suggestion = spellCheckResponse.getSuggestions().get(0);
List<String> alternatives = suggestion.getAlternatives();
String alternative = alternatives.get(0);
Ожидается, что ключевое слово «HME» заменит должен быть «домой», потому что наш индекс содержит термин «дом». Обратите внимание, что вы должны активировать проверку орфографии перед выполнением поиска.
7.2. Автоматически предлагать условия
Мы можем захотеть получить предложения по неполным ключевым словам, чтобы облегчить поиск. Предлагаемые Solr компоненты необходимо настроить вручную. Вы можете найти его в официальномwiki pageПодробности конфигурации можно найти в .
Мы настроили обработчик запросов под названием /suggest для обработки предложений. Давайте получим предложения по ключевому слову «Хом»:
SolrQuery query = new SolrQuery();
query.setRequestHandler("/suggest");
query.set("suggest", "true");
query.set("suggest.build", "true");
query.set("suggest.dictionary", "mySuggester");
query.set("suggest.q", "Hom");
QueryResponse response = solrClient.query(query);
SuggesterResponse suggesterResponse = response.getSuggesterResponse();
Map<String,List<String>> suggestedTerms = suggesterResponse.getSuggestedTerms();
List<String> suggestions = suggestedTerms.get("mySuggester");
Список предложений должен содержать все слова и фразы. Обратите внимание, что у нас есть подсказчик с именем mySuggester, настроенный в конфигурации.
8. Заключение
В этой статье представлено краткое введение в возможности и функции поисковой системы Solr.
Мы говорили о многих функциях, но это, конечно, только представление о том, что мы можем делать с продвинутым и полноценным поисковым сервером, таким как Solr.
Примеры, использованные здесь, можно найти наGitHubиспользовать на.