2

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

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 示例在我的应用程序中使用 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'));
}

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

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

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

  return $ret;
}

只要这个人是在运行时创建的,它就可以正常工作,但是如果从固定装置加载,则getUsernames()不会返回任何内容。代码执行了两次(一次是在加载 Person 时,一次是在添加用户名时)。这有什么原因吗?我能以某种方式解决这个问题吗?

这样做的另一种方式也将不胜感激。Lucene 似乎可以使用 Zend_Lucene_Search_Interface_MultiSearcher 类搜索多个索引,如本问题所述。但是,我似乎无法让这个工作。

我在这里发现了一个类似的问题,但没有找到任何指针。

我现在使用 Propel 1.6。

4

1 回答 1

1

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

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

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

调用 $username->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->getUsernames() 不会自动从 db 获取用户名,因为列表已经非空。

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

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

或者

<?php
$person = PersonPeer::retrieveByPk(123);
$person->getUsernames(); //trigger list fetch
于 2011-08-05T06:44:13.650 回答