7

いくつかのオブジェクトのタイトルと説明のテキスト検索を実装したいサイトを構築しています。オブジェクトの数が少ない(〜500ドキュメント)ので、Haystackなどは考慮していません。

必要な機能は2つだけです。

  • 説明よりもタイトルの一致を優先することができます(ある種の重みがあります)。
  • 文の部分一致を許可します。たとえば、「アイスクリーム」を検索すると、「アイス」と「クリーム」の結果も表示されます。

django-watsondjango-full-text-searchを調べましたが、部分一致が許可されているかどうかはわかりません。何か案は?

4

6 に答える 6

3

あなたのサイトは1秒あたり何回ヒットしていますか?各ドキュメント、データストアはいくつですか?

500のドキュメントについて話していて、分単位でヒット数が少ない場合は、おそらくdjangoapiで十分です。

q = None
for word in search_string.split():
   q_aux = Q( title__icontains = word ) | Q( description__icontains = word )
   q = ( q_aux & q ) if bool( q ) else q_aux

result = Document.objects.filter( q ) 

このオプションを検討したことがありますか?

気をつけて:

  • このアプローチでは、説明よりもタイトルを優先しません
  • 「すべての単語」の一致のみが結果に表示されます。
于 2012-07-21T19:32:59.167 に答える
3

django-watsonの作成者として、一部のデータベースバックエンドでは、部分一致が可能であることを確認できます。具体的には、MySQLとPostgreSQLでは、単語の先頭からの部分一致であるプレフィックス一致が可能です。

ウィキのこのデータベース比較ページをチェックしてください:

https://github.com/etianen/django-watson/wiki/Database-support

于 2013-02-05T10:05:52.623 に答える
3

開始点として新しい全文検索をdjango.contrib.postgresSearchQuery使用すると、拡張して、最後の単語の一部の検索を処理するバージョンを作成できます。

from psycopg2.extensions import adapt
from django.contrib.postgres.search import SearchQuery


class PrefixedPhraseQuery(SearchQuery):
    """
    Alter the tsquery executed by SearchQuery
    """

    def as_sql(self, compiler, connection):
        # Or <-> available in Postgres 9.6
        value = adapt('%s:*' % ' & '.join(self.value.split()))

        if self.config:
            config_sql, config_params = compiler.compile(self.config)
            template = 'to_tsquery({}::regconfig, {})'\
                .format(config_sql, value)
            params = config_params

        else:
            template = 'to_tsquery({})'\
                .format(value)
            params = []

        if self.invert:
            template = '!!({})'.format(template)
    
        return template, params

ts_query構文については、Postgresのドキュメントを参照してください

次に、次のようなクエリで使用できます。

vector = SearchVector(  
    'first_name',
    'last_name',
    'email',
    config='simple')
query = PrefixedPhraseQuery(query, config='simple')
queryset = queryset\
    .annotate(vector=vector)\
    .filter(vector=query)

ルックアップを作成することもできます。startswithの実装を参照してくださいSearchVectorExact

Django3+回答

これは、Djangoの最近のバージョンでははるかに簡単になっています。プレフィックスクエリをリクエストするために使用できるモードが追加されましたSearchQueryraw

query = SearchQuery("search & term & prefix:*", search_type="raw")
results = Model.objects\
    .filter(_search_vector=query)\
    .annotate(
        rank=SearchRank(
            F("_search_vector"),
            query,
            cover_density=True,
        )
    )
    .order_by("-rank")

_search_vectorは、、SearchVectorFieldまたはモデルに注釈を付けることができます。

于 2017-04-19T03:51:13.783 に答える
2

この記事をチェックしてください。それはあなたがやろうとしていることについての情報を持っています。

Haystackも見てください。Whooshは良い選択肢のようです。

于 2012-07-21T18:21:30.837 に答える
0

私は自分のプロジェクトでApacheSolrを使用しましたが、それは非常に優れており、大量のドキュメントがあります。そして、日焼け、pysolrsolrpyをチェックしてください

于 2012-07-22T14:40:25.543 に答える
0

全文検索がDjangoでサポートされるようになりました:Django全文検索

重要:これはpostgresdbバックエンドでのみ有効になっているようです。

# Example based on Django Docs.
Entry.objects.annotate(
   search=SearchVector('title', 'description'),
).filter(search='some_text')

検索ルックアップを使用することもできます

Entry.objects.filter(title__search='Cheese')
于 2018-05-28T17:44:16.150 に答える