1

検索用のdjangoアプリケーションでhaystackを使用していますが、検索は非常にうまく機能しています。しかし、リアルタイム検索に問題があります。リアルタイム検索には、haystack のデフォルトの RealTimeSignalProcessor(haystack.signals.RealtimeSignalProcessor) を使用しています。私のモデルには、多対多のフィールドが 1 つ含まれています。この多対多フィールドのみのデータが変更された場合、リアルタイム シグナル プロセッサがインデックス データを適切に更新していないようです。多対多のデー​​タを更新した後、間違った検索結果が表示されます。

手動で rename_index コマンドを実行した後に機能します。最初にクリーニングを行い、次にインデックス作成データを再度構築するため、rebuild_index が機能していると思います。

誰かが問題の解決策を提案できますか?

ちなみに、以下はその周りのコードです。

モデル:

class Message_forum(models.Model):
      message = models.ForeignKey(Message)
      tags = models.ManyToManyField(Tag, blank=True, null=True) #this is many to many field

search_index.py:

class Message_forumIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.EdgeNgramField(document=True, use_template=True)
    message = indexes.CharField(model_attr='message', null=True)
    tags = indexes.CharField(model_attr='tags', null=True)

    def get_model(self):
        return Message_forum

    def index_queryset(self, using=None):
        return self.get_model().objects.all()

    def prepare_tags(self, obj):
        return [tag.tag for tag in obj.tags.all()]

索引テンプレート:

{{ object.tags.tag }}

settings.py:

HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

バックエンドとして haystack と whoosh の最新バージョンを使用しています。

4

3 に答える 3

9

haystack のコードを掘り下げた後、私はそれを理解しました。

haystack のデフォルトの RealTimeSignalProcessor では、アプリケーションの各モデルの post_save シグナルと post_delete シグナルを接続しています。これで、handle_save メソッドが post_save および post_delete シグナルで呼び出されます。このメソッドでは、haystack が送信者を検証しています。私の場合、tags(many-to-many) フィールドでは、Message_forum_tag モデルが送信者として渡されています。このモデルのインデックスは、私のアプリケーション モデルではなく、django が生成したモデルであるため、search_index には存在しません。したがって、handle_save メソッドでは、このモデルの変更をバイパスしていたため、変更されたオブジェクトのインデックス付きデータを更新していませんでした。

したがって、この問題に対する2つの異なる解決策を見つけました。

  1. モデル Message_forum に固有のカスタム リアルタイム シグナル プロセッサを作成できます。このセットアップ メソッドでは、Message_forum の各多対多フィールドで m2mchanged シグナルを handle_save に接続できます。同時に、送信者として Message_forum を渡すことができるので、haystack は検証 (厳密には検証ではなく、そのインデックス obj を取得しようとしています) を通過し、変更されたオブジェクトのインデックス データを更新します。

  2. もう 1 つの方法は、多対多フィールドが変更されるたびに、その親の save メソッド (ここでは Message_forum.save()) が呼び出されるようにすることです。そのため、常に post_save シグナルが呼び出され、その後 haystack はインデックス オブジェクト データを更新します。

それを理解するために約3時間を費やしています。これが同じ問題を抱えている人に役立つことを願っています。

于 2013-11-01T07:50:18.130 に答える