Справка Zend_Search_Lucene - PullRequest
       9

Справка Zend_Search_Lucene

2 голосов
/ 08 августа 2009

EDIT:

Мне удалось решить проблему с помощью:

+"lorem ipsum" +type:photo
+"lorem ipsum" +type:video

Другая проблема заключается в том, что индекс возвращает правильные результаты, но с неверным идентификатором (идентификатор является первичным ключом). Более конкретно, возвращаемые поля идентификаторов на 1 меньше, чем реальные идентификаторы (id - 1) в базе данных, которую я использую для построения индекса.

Это очень странно.


Что не так с этими поисковыми запросами:

"lorem ipsum" AND +type:photo
"lorem ipsum" AND +type:video

Первый запрос должен найти только результаты с type = photo, второй - только видео. Но они оба возвращают фотографии и видео.

Вот как я строю индекс:

    // create media index
    $index = Zend_Search_Lucene::create('/data/media_index');
    // get all media
    $media = $this->_getTable('Media')->get();
    // iterate through media and build index
    foreach ($media as $m) {

        $doc = new Zend_Search_Lucene_Document();

        $doc->addField(Zend_Search_Lucene_Field::UnIndexed('id',
                                                           $m->id));
        $doc->addField(Zend_Search_Lucene_Field::UnIndexed('thumb_path',
                                                           $m->thumb_path));
        $doc->addField(Zend_Search_Lucene_Field::Keyword('title',
                                                         $m->title));
        $doc->addField(Zend_Search_Lucene_Field::UnStored('description',
                                                          $m->description));
        $doc->addField(Zend_Search_Lucene_Field::Keyword('type',
                                                         $m->type));

        $index->addDocument($doc);

    }
    // commit the index
    $index->commit();

А вот как я ее ищу:

    $index = Zend_Search_Lucene::open('/data/media_index');
    $this->view->photos = $index->find('"lorem ipsum" AND +type:photo');
    $this->view->videos = $index->find('"lorem ipsum" AND +type:video');

Есть идеи?

Ответы [ 2 ]

2 голосов
/ 08 августа 2009

О «проблеме с идентификатором». Я бы предположил, что «id» - это внутренняя переменная, используемая для доступа к каждому результату. Поэтому я бы рекомендовал переименовать поле в sth. как "entryId", а затем использовать $resultItem->entryId

2 голосов
/ 08 августа 2009

Я только что выполнил несколько тестов по своему поисковому индексу, и проблема, похоже, в самом запросе, а не в коде. «И» в запросе является оператором, как и «+». Парсер запросов, похоже, смущен логикой двойного оператора без термина между. Это была блочная цитата, которую я нашел в их документах:

Если используется стиль И / ИЛИ / НЕ, то оператор И или ИЛИ должен присутствовать между всеми терминами запроса. Каждому члену также может предшествовать оператор NOT. Оператор AND имеет более высокий приоритет, чем оператор OR. Это отличается от поведения Java Lucene.

Теперь, выполняя ваш запрос через анализатор, это был объект Search_Query:

string '"lorem ipsum" AND +type:photo' (length=29)

object(Zend_Search_Lucene_Search_Query_MultiTerm)[230]
  private '_terms' => 
    array
      0 => 
        object(Zend_Search_Lucene_Index_Term)[236]
          public 'field' => null
          public 'text' => string 'lorem' (length=5)
      1 => 
        object(Zend_Search_Lucene_Index_Term)[237]
          public 'field' => null
          public 'text' => string 'ipsum' (length=5)
      2 => 
        object(Zend_Search_Lucene_Index_Term)[238]
          public 'field' => null
          public 'text' => string 'and' (length=3)
      3 => 
        object(Zend_Search_Lucene_Index_Term)[239]
          public 'field' => null
          public 'text' => string 'type' (length=4)
      4 => 
        object(Zend_Search_Lucene_Index_Term)[240]
          public 'field' => null
          public 'text' => string 'photo' (length=5)

Немного изменив запрос, удалив AND или удалив +, и используя только 1.

string '"lorem ipsum" +type:photo' (length=25)
string '"lorem ipsum" AND type:photo' (length=28)

object(Zend_Search_Lucene_Search_Query_Boolean)[227]
  private '_subqueries' => 
    array
      0 => 
        object(Zend_Search_Lucene_Search_Query_Phrase)[230]
          private '_terms' => 
            array
              0 => 
                object(Zend_Search_Lucene_Index_Term)[233]
                  public 'field' => null
                  public 'text' => string 'lorem' (length=5)
              1 => 
                object(Zend_Search_Lucene_Index_Term)[234]
                  public 'field' => null
                  public 'text' => string 'ipsum' (length=5)
      1 => 
        object(Zend_Search_Lucene_Search_Query_Term)[235]
          private '_term' => 
            object(Zend_Search_Lucene_Index_Term)[232]
              public 'field' => string 'type' (length=4)
              public 'text' => string 'photo' (length=5)

Единственная разница: AND:

  private '_signs' => 
    array
      0 => boolean true
      1 => boolean true

+:

  private '_signs' => 
    array
      0 => null
      1 => boolean true

Оператор AND требует, чтобы в результате требовались оба поисковых запроса, тогда как для + требуется только значение справа.

Так что просто измените запрос на

"lorem ipsum" AND type:photo

И вы должны получить результаты, которые вы ищете.

...