使用Zend Lucene索引相关实体

时间:2011-07-25 13:05:25

标签: zend-framework symfony1 lucene propel zend-lucene

我已在我的应用程序中设置搜索,但希望将其扩展为以一对多方式索引相关属性。例如,一个人可以拥有许多用户名,因此必须将它们分开,如下例所示:

person:
  id:         ~
  name:       {type: varchar(100), required: true}

username:
  person_id:  {type: integer, foreignTable: person, foreignReference: id}
  username:   {type: varchar(20), primaryKey: true, required: true}

到目前为止,我已经跟随Jobeet example在我的应用程序中使用Zend Lucene,我可以搜索Person中名称的属性,例如Name。

我找不到任何方法通过Symfony或Lucene自动执行此操作,因此我尝试在Person的索引中添加项目,如下所示:

foreach ($this->getUsernames() as $i => $username)
{
  $doc->addField(Zend_Search_Lucene_Field::Text('username' . $i,
      $username->getUsername(), 'utf-8'));
}

然后,每当通过更新Username的保存功能添加新用户名时,我都会尝试更新此索引:

public function save(PropelPDO $con = null)
{
  $ret = parent::save($con);

  // reindex the person
  $person = $this->getPerson();
  $person->save();

  return $ret;
}

只要在运行时创建人员,这样就可以正常工作,但如果从灯具加载,getUsernames()则不返回任何内容。代码执行两次(一次加载Person,一次加入Username)。这有什么理由吗?我可以以某种方式解决这个问题吗?

另一种做法的方法也将受到赞赏。似乎Lucene可以使用Zend_Lucene_Search_Interface_MultiSearcher类搜索多个索引,如this question中所述。但是,我似乎无法使其发挥作用。

我发现了一个类似的问题here,但没有找到指针。

我现在正在使用Propel 1.6。

1 个答案:

答案 0 :(得分:1)

您没有指定您使用的推进版本。看到你正在使用PDO,你很可能正在使用1.3 +。

如果Username对象初始化正确,即:

<?php
$username = new Username();
$username->setUsername('foobar');
$username->setPerson($person);

调用$ username-&gt; save();应该触发$ person的save(),$ person对象也应该包含Username对象。

但是对于$ person初始化,有一个“功能”。 (有些人可能称之为错误..)

如果您初始化$ person,请执行以下操作:

$person = PersonPeer::retrieveByPk(123);
//or for 1.5+
$person = PersonQuery::create()->findPk(123);

$ person的用户名列表将为空。当你打电话

 $username->setPerson($person);

$ username将被添加到$ person的用户名列表中,这反过来意味着调用$ person-&gt; getUsernames()将不会自动从db获取用户名,因为列表已经非空。< / p>

因此您需要使用用户名初始化$ person。要么

<?php
$person = PersonQuery::create()->joinWith('Person.Usernames')->filterById(123)->findOne();

<?php
$person = PersonPeer::retrieveByPk(123);
$person->getUsernames(); //trigger list fetch