2

アプリケーションで検索を設定しましたが、1 対多の方法で関連するプロパティにインデックスを付けるように拡張したいと考えています。たとえば、1 人が複数のユーザー名を持つことができるため、次の例のように、ユーザー名を分けておく必要があります。

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}

ここまでは、アプリケーション内で Zend Lucene を使用するためにJobeet の例に従ってきました。また、Name など、Person 内の名前のプロパティを検索できます。

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()は何も返しません。コードは 2 回実行されます (Person のロード中に 1 回、ユーザー名の追加時に 1 回)。これには何か理由がありますか?どうにかしてこれを回避できますか?

これを行う別の方法も高く評価されます。この質問で説明されているように、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 の Usernames-list は空になります。そして電話すると

 $username->setPerson($person);

$username は $person の Usernames-list に追加されます。これは、$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 に答える