Zend_Search_Lucene帮助

时间:2009-08-08 01:41:59

标签: php zend-framework lucene search-engine

修改

我设法通过使用:

来解决问题
+"lorem ipsum" +type:photo
+"lorem ipsum" +type:video

另一个问题是索引返回正确的结果但ID错误(id是主键)。更具体地说,返回的id字段比我用来构建索引的数据库中的实际ID(id-1)少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 个答案:

答案 0 :(得分:2)

我刚刚对自己的搜索索引进行了一些测试,问题似乎出现在查询本身而不是代码中。查询中的“AND”是运算符,“+”也是。查询解析器似乎被双运算符逻辑混淆,两者之间没有术语。这是我在他们的文档中找到的块引用:

  

如果使用AND / OR / NOT样式,则所有查询术语之间必须存在AND或OR运算符。每个术语也可以在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

你应该得到你想要的结果。

答案 1 :(得分:2)

关于“id问题”我猜“id”是用于访问每个结果的内部变量。所以我建议将字段重命名为某事。比如“entryId”然后使用$resultItem->entryId