【问题标题】:Indexing Related Entities Using Zend Lucene使用 Zend Lucene 索引相关实体
【发布时间】:2011-07-25 13:05:24
【问题描述】:

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

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'));
}

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

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 类搜索多个索引,如this question 中所述。但是,我似乎无法正常工作。

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

我现在使用 Propel 1.6。

【问题讨论】:

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


    【解决方案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
    

    【讨论】:

    • 非常感谢您的回复。不幸的是,我不知道如何将其应用于我的问题。我目前在 Username.php 中覆盖的唯一函数是 save(),它目前看起来与我发布的完全一样。如果我自己不打电话给$person-&gt;save(),那根本不会。你建议它应该吗?我应该把上面的 Person 初始化放在哪里?在用户名的setPerson() 中,还是覆盖doSave()
    • 嗯..似乎我记错了这种行为..在我的示例案例中调用 $username->setPerson($person);实际上调用 $person->addUsername($username);然后实际上初始化集合。至少1.5+。因此,对于初始化集合,您不必做任何特别的事情。然后您的代码应该可以工作。用户名集合应在您的人员的保存方法中完全初始化。仅当实际修改此人时才调用此人的保存方法,因此您必须手动调用,就像您正在做的那样。
    • 你知道为什么用户名可能没有在 Person 中初始化吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-06
    • 2011-03-05
    • 1970-01-01
    • 2011-03-03
    相关资源
    最近更新 更多