Статьи

Solr 4.0: DocTransformers первый взгляд

В сегодняшней записи мы рассмотрим следующую функцию, которая появится в версии 4.0 Apache Solr. Мы рассмотрим функциональность, которая позволяет нам изменять поля в списках результатов Solr.

Мне это нужно?

До сих пор у нас не было большого выбора, когда дело дошло до результатов, возвращаемых Solr. Когда Solr 4.0 будет опубликован, нам будет предоставлен новый инструмент под названием DocTransformers . Эта функция позволяет нам изменять поля документов, возвращаемых Solr в результатах поиска. Глядя на то, что доступно сейчас, мы можем, например, изменить имена возвращенных полей или пометить документы, которые были добавлены QueryElevationComponent . В настоящее время есть только несколько реализаций, но реализовать собственный DocTranformer не сложно.

Что уже доступно?

В тот момент, когда мы пишем это, доступны следующие трансформаторы:

  • Тот, который позволяет пометить документы, которые были добавлены QueryElevationComponent .
  • Тот, который позволяет вам добавить информацию объяснения к документу.
  • Тот, который позволяет вам добавить статическое значение в качестве поля документа.
  • Тот, который позволяет вам добавить осколок, если документ был выбран.
  • Тот, который позволяет вам добавить документ в качестве поля документа (идентификатор, используемый Lucene).

Как использовать DocTransformers?

Давайте посмотрим, как использовать DocTransformers . Для этого я загрузил транковую версию Apache Solr (4.0) из репозитория svn и запустил пример развертывания. Затем я проиндексировал данные примера и выполнил следующий запрос:

 
http://localhost:8983/solr/select?q=encoded&fl=name,score,[docid],[explain]

Если вы посмотрите на параметр fl, вы заметите, что мы сказали Solr, что нам нужны поле имени в результатах, счет документа и два DocTransformers : [docid] и [объяснение] . В результате я получил следующий XML:

<?xml version="1.0" encoding="UTF-8"?>
<response>
 <lst name="responseHeader">
  <int name="status">0</int>
  <int name="QTime">2</int>
  <lst name="params">
    <str name="q">encoded</str>
    <str name="fl">name,score,[docid],[explain]</str>
  </lst>
 </lst>
 <result name="response" numFound="2" start="0" maxScore="0.50524884">
 <doc>
  <str name="name">Test with some GB18030 encoded characters</str>
  <float name="score">0.50524884</float>
  <int name="[docid]">0</int>
  <str name="[explain]">
  0.50524884 = (MATCH) weight(text:encoded in 0) [DefaultSimilarity], result of:
    0.50524884 = score(doc=0,freq=1.0 = termFreq=1), product of:
      1.0000001 = queryWeight, product of:
        3.2335923 = idf(docFreq=2, maxDocs=28)
        0.3092536 = queryNorm
      0.5052488 = fieldWeight in 0, product of:
        1.0 = tf(freq=1.0), with freq of:
          1.0 = termFreq=1
        3.2335923 = idf(docFreq=2, maxDocs=28)
        0.15625 = fieldNorm(doc=0)
  </str>
 </doc>
 <doc>
  <str name="name">Test with some UTF-8 encoded characters</str>
  <float name="score">0.4041991</float>
  <int name="[docid]">25</int>
  <str name="[explain]">
  0.4041991 = (MATCH) weight(text:encoded in 25) [DefaultSimilarity], result of:
    0.4041991 = score(doc=25,freq=1.0 = termFreq=1), product of:
      1.0000001 = queryWeight, product of:
        3.2335923 = idf(docFreq=2, maxDocs=28)
        0.3092536 = queryNorm
      0.40419903 = fieldWeight in 25, product of:
        1.0 = tf(freq=1.0), with freq of:
          1.0 = termFreq=1
        3.2335923 = idf(docFreq=2, maxDocs=28)
        0.125 = fieldNorm(doc=25)
  </str>
 </doc>
</result>
</response>

Как видите, Solr сделал то, что мы просили.

Ваша собственная реализация

Давайте обсудим, кто для реализации вашего DocTransformer . Ниже приведен пример класса RenameFieldsTransformer из пакета org.apache.solr.response.transform в исходном коде Apache Solr. В общем, все, что вам нужно сделать, это переопределить следующие два метода из класса DocTransformer из пакета org.apache.solr.response.transform :

  • String getName () — метод, возвращающий имя преобразователя,
  • void transform (SolrDocument doc, int docid) — метод, который выполняет фактическое преобразование.

Реализация выглядит так:

public class RenameFieldsTransformer extends DocTransformer {
 final NamedList<String> rename;

 public RenameFieldsTransformer( NamedList<String> rename ) {
  this.rename = rename;
 }

 @Override
 public String getName() {
  StringBuilder str = new StringBuilder();
  str.append( "Rename[" );
  for( int i=0; i< rename.size(); i++ ) {
   if( i > 0 ) {
    str.append( "," );
   }
   str.append( rename.getName(i) ).append( ">>" ).append( rename.getVal( i ) );
  }
  str.append( "]" );
  return str.toString();
 }

 @Override
 public void transform(SolrDocument doc, int docid) {
  for( int i=0; i<rename.size(); i++ ) {
   Object v = doc.remove( rename.getName(i) );
   if( v != null ) {
    doc.setField(rename.getVal(i), v);
   }
  }
 }
}

Приведенный выше код позволяет нам переименовывать поля, возвращаемые в результатах. Как вы можете видеть,
метод
transform перебирает все значения в
переменной класса
переименования .
Переименования переменной состоят из пар имя — значение , которые являются имя поля и имя оно должно иметь после преобразования. Вы также должны помнить, что для использования вашего собственного преобразователя вам необходимо добавить его конфигурацию в
файл
solrconfig.xml . Вот пример, который можно найти на вики-странице Solr:

<transformer name="elevated" class="org.apache.solr.response.transform.EditorialMarkerFactory" />

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

Вы должны помнить, что функциональность DocTransformer помечена как экспериментальная и может изменить свое поведение при выходе Lucene и Solr 4.0. Мы вернемся к этой теме, как только будет выпущен Solr 4.0.