Django + Sphinx = django-sphinx(?)





Django-batteriesに関する Habrの最後の記事 準備したとき、django-sphinxについて伝えるべきことがまだあることがわかりました。 実際、約束どおり彼はここにいます。



現在、Djangoで検索を整理するための優れたソリューションがいくつかあります。 Haystackdjango-sphinxの 2つがあります。 Haystackはsolr、whoosh、およびhapianバックエンドで動作しますが、悲しいことに、いくつかの抽象的なライセンス上の理由でSphinxで動作しません。 ご想像のとおり、django-sphinxはSphinxでのみ動作します。 Haystackは高品質で、十分に文書化され、積極的に開発された製品であり、Sphinxを何らかの形でサポートしていれば間違いなく使用できます。 しかし、悲しいかな、これはまだ起こっていません。 そして、 スフィンクスはそのスピード、柔軟性、そして地理的緯度において非常に重要であり、ロシアの形態の特徴を考慮する能力のおかげで私たちのすべてです。 「大きいが、5 ...または小さいが、3?」







検索結果の品質は依然として重要であるため、検索エンジンを選択することは大した問題ではありませんでした。 また、django-sphinx以外には「jangosphinx」という性質が存在しないため、バッテリーの選択は事前に事前に決定されています。 だから:



良い:


悪い:




もちろん、Sphinx自体の配信に含まれているPython APIを使用することもできます。これは、 magic4xを 提供したばかりです 。 ただし、3番目のオプションがあります- ブラックジャックテストとドキュメントを使用して、独自のバッテリーを作成する。



一方、すべてがそれほど悪くはありません。 Django-sphinxはさまざまなプロジェクトで成功裏に使用されており、全体として作業に対処しています。 現実の世界からの例を見てみましょう。



検索を整理する特定のモデルがあります。



class Post(models.Model): ... title = models.CharField(_(u''), max_length=1000) teaser_text = models.TextField(_(u''), blank=True) text = models.TextField(_(u'')) ... #  django-sphinx search = SphinxSearch(weights={'title': 100, 'teaser_text': 80, 'text': 90}) ...
      
      







Sphinx APIではなくdjango-sphinxを使用する主な理由の1つは、モデルで指定したデータに基づいてdjango-sphinxが自動的にsphinx構成を生成する機能です。 このために、特別な管理コマンドgenerate_sphinx_configがあります。 使い方は簡単です。



 $ ./manage.py generate_sphinx_config --all > absolute_path_to_config_file.conf
      
      







ところで、設定を生成するテンプレートの独自のセットを作成できます。 これらのテンプレートでは、検索モード 、ロシア語のステミングなどを指定できます。構成を手動で修正する必要はありません。 便利に。



次に、検索エンジンデーモン自体を起動する必要があります。 Django-sphinxは設定のこの部分とは関係ありません。Sphinxボックスのプログラムが使用されます。



 $ sudo searchd --config absolute_path_to_our_config_file.conf
      
      







最初の起動時に、 searchdはインデックスがなく、何の関係もないことを誓います。 インデックステーブルを作成するために、 インデクサープログラムが提供されます。これは、最も単純な場合、次のように始まります。



 $ sudo indexer --config absolute_path_to_our_config_file.conf --all --rotate
      
      







それだけです もちろん、これらの単純なアクションのために、開発者ごとに独自の構成とシステム内の独自のsphinxdインスタンスを作成する、より単純な管理チームでさえ書くことができます。 個人的にはそうしました。



それでは、検索をどのように設計しますか? django-sphinxは設定の作成以外に何ができますか?



たとえば、一部のビューでは、検索クエリオブジェクトを取得する必要があります。 とても簡単です:



 ... user_query = self.request.GET['query'] #   result = Post.search.query(user_query) ...
      
      







検索結果といくつかの便利なメソッドと属性を含む疑似 `queryset-object結果を取得します。 たとえば、Sphinxは独自に検索エンジンの結果スニペットを作成でき、少しカスタマイズすることもできます。



 passages_opts = {'before_match': '<span style="background-color: yellow">', 'match': '</span>', 'chunk_separator': '...', 'around': 10, 'single_passage': True, 'exact_phrase': True, } result = result.set_options(passages=True, passages_opts=passages_opts)
      
      







このコードが行うことは簡単に推測でき、異常なものは何もありません。 ただし、選択範囲をさらにフィルタリングする必要がある場合(ほぼ確実に該当します)、ここではドラゴンです。 すべてが完全に予想外の方法で動作し始めます。



バゴフィチャNo. 1

excludeおよびfilterメソッドを使用するには、フィルタリングされたオブジェクトのid'shikiを事前に収集し、それらを属性のアンパックディクショナリの形式で渡す必要があります(例で簡単に表示できます)



 excluded_obj_id_list = [post.id for post in result if post.is_published] filtered_result = result.exclude(**{'@id__in': excluded_obj_id_list})
      
      







そして、これについて最も予期しないことは、最後の操作が期待どおりに機能しないことです。 正直なところ、まったく機能しません。除外は発生しません。



バゴフィチャNo. 2

すべては、同じメソッドチェーン内でのみ期待どおりに機能します。



 filtered_result = Post.search.query(user_query).exclude(**{'@id__in': excluded_obj_id_list})
      
      







そしてもちろん、これは最も効率的で透過的なコードを生成しません。



バゴフィチャNo. 3

Sphinxにはさまざまな検索モードがあります。 たとえば、モードを 'SPH_MATCH_ANY'に設定します(クエリワードのいずれかに一致します)。 モデル自体でこれを行うと、すべてがうまく機能します。



 search = SphinxSearch(weights={'title': 100, 'teaser_text': 80, 'text': 90}, mode='SPH_MATCH_ANY')
      
      







スニペットとその設定の生成をオンにするロジックでこれを行うと、すべてがうまく機能します...



 result = Post.search\ .query(user_query)\ .exclude(**{'@id__in': excluded_obj_id_list})\ .set_options(passages=True, passages_opts=passages_opts, mode='SPH_MATCH_ANY)
      
      







...しかし、スニペットは表示されません。 したがって、モデルでのみ検索モードを指定してください。



テンプレートでは、すべてが非常に簡単です。 したがって、たとえば、スニペットが表示されます。



 {% for post in search_results %} <div class="g-content"> <a href="{{ post.get_absolute_url }}" class="b-teaser__descr__snippet-link"> {{ post.sphinx.passages.text|safe }} </a> </div> {% endfor %}
      
      







言及された「機能」は多くの血を飲んだので、この投稿があなたの時間と神経を節約することを願っています。



そして最後に。 2011年12月、Sphinxの最初の新しいリリースがここ数年でリリースされました-バージョン2.0.3。 django-sphinxは、バージョン0.9.7、0.9.8および0.9.9でのみ「動作」します。






1)スフィンクス-sphinxsearch.com

2)オリジナルのdjango-sphinx-github.com/dcramer/django-sphinx

3)バグを修正したフォーク-github.com/futurecolors/django-sphinx



All Articles