2016-08-10 2 views
2

무료 버전을 사용했던 인트라넷 PHP + MySQL 응용 프로그램 인 Precurio를 기반으로 인트라넷 용 새 모듈을 개발하고 있습니다.Zend Framework의 Lucene 색인에 내용 추가

이 인트라넷은 Zend Framework 2.0을 사용하고 Lucene을 사용하여 검색 결과를 제공합니다. 인트라넷에 새 모듈을 추가 할 때마다 사용자가 삽입 한 모듈의 내용을 색인화하는 기능이 추가됩니다.

문제는 검색이 정상적으로 작동하지만 모든 인덱스를 처음부터 다시 작성해야하는 경우입니다. 모듈에 새 내용을 추가 할 때마다 검색 결과에 나타나지 않습니다. 색인의 전체 재구성 이전에 있었던 내용은 여전히 ​​검색 결과로 표시됩니다.

전체 색인을 다시 작성하는 함수는 루프에서 단일 항목을 추가하는 함수를 호출하기 때문에 매우 당황 스럽습니다. 따라서 가장 잘 알고있는 것처럼 동일하게 작동해야합니다. 하지만 분명히 그렇지 않습니다.

/** 
* Adds a cabinet to the index 
* @param $cabinet int | CabinetContent . you could either pass the cabinet_id or the CabinetContent object 
* @return void 
*/ 
public function indexCabinet($cabinet,$indexing = false) 
{ 
    if(!is_a($cabinet,'CabinetContent')) { 
     $cabinet = CabinetContents::getContent($cabinet); 
    } 

    if(Precurio_Utils::isNull($cabinet->title)) 
      return;//cabinets without a title will be ignored. 

    //check if the cabinet already exists 
    if(!$indexing) 
    { 
     $hits = $this->index->find('id:' . $cabinet->id.' AND module:cabinet'); 
     foreach ($hits as $hit) 
     { 
      $this->index->delete($hit->id); 
     } 
    } 
    try 
    { 
     $doc = new Zend_Search_Lucene_Document(); 
     $doc->addField(Zend_Search_Lucene_Field::keyword('id',$cabinet->id)); 
     $doc->addField(Zend_Search_Lucene_Field::text('title',$cabinet->title)); 
     if($cabinet->identifier != '') 
      $doc->addField(Zend_Search_Lucene_Field::text('identifier',$cabinet->identifier)); 
     if($cabinet->summary != '') 
      $doc->addField(Zend_Search_Lucene_Field::text('summary',$cabinet->summary)); 
     if($cabinet->body != '') 
      $doc->addField(Zend_Search_Lucene_Field::text('body',$cabinet->body)); 
     $doc->addField(Zend_Search_Lucene_Field::keyword('user_id',$cabinet->user_id)); 
     if(($cabinet->url != '#') && ($cabinet->url != '')) 
      $doc->addField(Zend_Search_Lucene_Field::text('url',$cabinet->url)); 
     if($cabinet->keyword != '') 
      $doc->addField(Zend_Search_Lucene_Field::text('keyword',$cabinet->keyword)); 
     if($cabinet->getFullName() != '') 
      $doc->addField(Zend_Search_Lucene_Field::text('fullname',$cabinet->getFullName())); 

     $doc->addField(Zend_Search_Lucene_Field::unIndexed('date_added',$cabinet->getDateAdded())); 
     $doc->addField(Zend_Search_Lucene_Field::keyword('module','cabinet')); 
    } 
    catch(Exception $e) 
    { 

    } 

    $this->index->addDocument($doc); 
    return; 
} 

이전 기능은 내가 createIndexFromDB를 실행할 때()를 작동하는 것 같다 :

내가 현재 개발하고 있어요 모듈에 대한 인덱싱 기능의 코드입니다. 이 인덱스를 다시 작성하는 데 사용되는 함수입니다 : 새 내각의 컨텐츠를 삽입 한 후, 내가 개발하고있는 모듈에서,

private $index; 
public function __construct() 
{    
    if(!file_exists(self::PATH_INDEX)) 
     $this->createIndexFromDb(); 
    else 
     $this->index = Zend_Search_Lucene::open(self::PATH_INDEX); 
} 
private function createIndexFromDb() 
{ 
    set_time_limit(0); 
    mkdir(self::PATH_INDEX); 
    $this->index = Zend_Search_Lucene::create(self::PATH_INDEX); 
    $this->indexCabinets(); // Cabinets is the module I am developing 
    /* Here go a lot of indexing for other modules, like $this->indexEmployees(); but I have commented it out for simplicity during developement */ 
} 

private function indexCabinets() 
{ 
    $table = new Zend_Db_Table(array('name'=>PrecurioTableConstants::CABINET_CONTENT,'rowClass'=>'CabinetContent')); 
    $select = $table->select(false); 
    $select->setIntegrityCheck(false); 
    $select->setTable($table); 

    $select = $select->distinct() 
        ->from(array('a' => PrecurioTableConstants::CABINET_CONTENT)) 
        ->join(array('b' => PrecurioTableConstants::USERS),'a.user_id = b.user_id',array('first_name','last_name','profile_picture_id')) 
        ->where('a.active=1'); 
    $cabinets = $table->fetchAll($select); 
    foreach($cabinets as $cabinet) 
    { 
     $this->indexCabinet($cabinet,true); 
    } 
} 

지금, 나는 다음과 같은 코드를 실행합니다

$dict = new My_Search(); 
$dict->indexCabinet($content_id); 
$this->_redirect('/cabinet/view/index'); 

을하지만 '아무튼 일하지 마라. 나는 $ dict-> indexCabinet을 'true'를 두 번째 매개 변수로 사용하여 $ content_id가 아닌 검색 클래스에서 $ content 객체를 전달하는 것으로 호출하려고 시도했습니다 ... 나는 잘못된 것을 알지 못합니다. 또 무엇을 시도 할 것인가.

모든 새로운 모듈은 Precurio 인트라넷의 원래 모듈과 My_Search 클래스의 추가 모듈을 기반으로한다는 것을 분명히해야합니다. 내가 아는 한, 새로운 내용의 색인 생성은 원래 코드에서 작동하지 않았을 수 있습니다. 어떤 도움이라도 대단히 감사하겠습니다.

** 편집 2016년 10월 8일 : 나는 당신이 제공 한 코드 (내 친숙 함과 함께 사용되는 방법을 정확하게 볼 아주 확실하지 않다

답변

0

위의 코드에 원래 클래스의 생성자를 추가 Zend는 언제나 최고의 감동을주고 받는다.) 그러나 이것은 꽤 일반적인 lucene 실수 (기존 색인을 열지 않고 새 색인 만들기)와 일치하는 것으로 들린다.

완전히 새로운 색인을 만들려면 Zend_Search_Lucene::create을 사용해야합니다. 지정된 위치의 기존 색인이 모두 삭제됩니다.

기존 인덱스를 열려면 Zend_Search_Lucene::open을 사용해야합니다.

이 젠드의 처음 두 예제를 참조하십시오. "Building Indexes" documentation.

+0

내일 직장에서 시험 해보고 작동하는지 알려 드리겠습니다. 감사! – akhasis

+0

위대한, 그게 나에게 당신이 제공 한 링크를 적용하여 각 인덱싱 함수의 시작 부분에 다음 라인을 추가하여 작동하도록 유도했다. "$ index = Zend_Search_Lucene :: open (self :: PATH_INDEX);" .여전히, 나는 원래의 코드가 작동하지 않는 이유를 모르겠다 : 나는 그것도 같았지만, $ index를 사용하는 대신 클래스 private variable $ this-> index를 사용하여 생성자에서 인덱스를 연다. $ this-> index = Zend_Search_Lucene :: open (self :: PATH_INDEX); 원래 질문을 편집하여 생성자 코드를 추가했습니다. – akhasis