Статьи

Простой поиск фотографий с Solr и Tika

Недавно у нас было изменение, чтобы помочь с некоммерческим проектом, который включал поиск в качестве его части. Одним из предположений, хотя и не ключевых, была функция поиска фотографий, чтобы пользователь мог быстро и точно находить изображения. Поскольку поиск должен был работать с метаданными файлов JPEG, идея была проста — использовать Apache Solr с Apache Tika.

Предположения

Предположения были довольно просты — пользователь должен быть в состоянии найти фотографии по имени файла, автору и другим данным, доступным в EXIF, таким как диафрагма, выдержка, фокусное расстояние или значение ISO. Другое дело, что Solr должен позаботиться о получении метаданных из файлов JPEG, поэтому мы определенно хотели использовать ячейку Solr. Как видите, эти предположения были просты.

Структура индекса

Структура индекса была очень простой и содержала только самые необходимые поля. Раздел полей файла schema.xml выглядел следующим образом:

<field name="id" type="string" indexed="true" stored="true" required="true" />
<field name="name" type="text" indexed="true" stored="true" />
<field name="author" type="text" indexed="true" stored="true" />
<field name="iso" type="text" indexed="true" stored="true" multiValued="true" />
<field name="iso_string" type="text" indexed="true" stored="true" multiValued="true" />
<field name="aperture" type="double" indexed="true" stored="true" />
<field name="exposure" type="string" indexed="true" stored="true" />
<field name="exposure_time" type="double" indexed="true" stored="true" />
<field name="focal" type="string" indexed="true" stored="true" />
<field name="focal_35" type="string" indexed="true" stored="true" />
<dynamicField name="ignored_*" type="string" indexed="false" stored="false" multiValued="true" />

Динамическое поле было добавлено, чтобы игнорировать данные, которые нас не интересовали. Также было введено copyField для копирования значения поля iso в поле iso_string для включения фасетирования.

Конфигурация Solr

Следующее определение обработчика было добавлено в файл solrconfig.xml :

<requestHandler name="/update/extract" class="solr.extraction.ExtractingRequestHandler">
 <lst name="defaults">
  <str name="uprefix">ignored_</str>
  <str name="lowernames">true</str>
  <str name="captureAttr">true</str>
  <str name="fmap.stream_name">name</str>
  <str name="fmap.artist">author</str>
  <str name="fmap.exif_isospeedratings">iso</str>
  <str name="fmap.exif_fnumber">aperture</str>
  <str name="fmap.exposure_time">exposure</str>
  <str name="fmap.exif_exposuretime">exposure_time</str>
  <str name="fmap.focal_length">focal</str>
  <str name="fmap.focal_length_35">focal_35</str>
 </lst>
</requestHandler>

Несколько слов о конфигурации. Параметр uprefix сообщает Solr, какой префикс он должен использовать для полей, которые не были явно упомянуты в конфигурации обработчика. В приведенном выше случае поля, которые не были упомянуты, будут иметь префикс с словом ignored_ . Это означает, что они будут сопоставлены с динамическим полем и, следовательно, они не будут проиндексированы ( сохранены = «ложь» и проиндексированы = «ложь» ). Параметр lowernames со значением true приведет к тому, что все имена полей будут в нижнем регистре. captureAttrпараметр скажи Solr, чтобы ловить атрибуты файла. Следующими параметрами в приведенной выше конфигурации является определение соответствия между полями, возвращаемыми Тикой, и полями в индексе. Например, fmap.exif_fnumber со значением апертуры говорит Solr, чтобы поместить значение Tika exif_fnumber в поле индекса апертуры .

Дополнительные, необходимые библиотеки

Для того чтобы вышеуказанная конфигурация работала, нам нужны дополнительные библиотеки (аналогичные тем, которые описаны в идентификации языка ). Из каталога dist , доступного в дистрибутиве Solr, мы копируем файл apache-solr-cell-3.5.0.jar в каталог tikaDir, который должен быть создан на том же уровне, что и каталог webapps при развертывании Solr (конечно, это пример ). Затем мы добавляем следующее как в файл solrconfig.xml :

<lib dir="../tikaLib/" />

Выше указано, что Solr включает все библиотеки из данного каталога. Далее нам нужно скопировать все jar-файлы из каталога дистрибуции contrib / extract / Solr в созданный каталог tikaDir . Дополнительные изменения в solrconfig.xml не нужны.

Индексация данных

Предполагалось, что в неделю будет около 10 000 новых фотографий, которые необходимо будет проиндексировать. Эти фотографии будут храниться в общей файловой системе. Простой bash-скрипт отвечал за выбор файлов, которые необходимо было проиндексировать, и во время своей работы запускал следующую команду для каждого файла:

curl 'http://solrmaster:8983/solr/photos/update/extract?literal.id=9926&commit=true" -F "myfile=@Wisla_2011_10_10.JPG"

Приведенная выше команда отправляет файл с именами Wisla_2011_10_10.JPG в обработчик / extract и говорит, что нужно выполнить команду commit после ее обработки. Кроме того, задается уникальный идентификатор файла ( параметр literal.id ).

Запросы

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

q=jan+kowalski+wisla&qf=name^100+author^1000+iso+aperture+exposure_time+focal&defType=dismax

Как видите, запрос прост. Два поля в индексе более ценны, чем другие — название фотографии и ее автора. Значение этих полей было установлено путем добавления увеличения времени запроса. Остальные поля не имеют усиления, поэтому применяется усиление по умолчанию 1.

Подводить итоги

Описанное развертывание действительно просто. Приложение работает как поиск :). Следующие шаги, которые необходимо выполнить, — это настройка JVM и Solr. Одной из самых важных вещей будет рассмотрение поведения пользователей и настройка поиска, чтобы сделать поиск максимально эффективным. Но давайте оставим это для другого сообщения solr.pl.

Источник:  http://solr.pl/en/2012/02/20/simple-photo-search/