sql >> データベース >  >> RDS >> PostgreSQL

django1.10でトリグラムとランク付けされた検索を組み合わせる

    検索がどのように重要であるかをより徹底的に理解するために調査しました。

    ドキュメント によると フィールドに応じて重みを割り当てることができ、重みを割り当てることもできます。同様に、トリグラム 類似性または距離でフィルタリングします。

    ただし、この2つを使用してさらに調査する例を指定しないでください。また、ウェイトが機能することも理解できません。

    少し論理的に言えば、すべてで共通の単語を探すと、すべてランク0になります。類似性は範囲よりもはるかに大きく異なりますが、その範囲の値は低くなる傾向があります。

    現在、テキスト検索は、私たちが理解している限り、構成に配置されている言語よりもさらにフィルタリングしたいフィールドに含まれているテキストに基づいて実行されます。たとえば、タイトルを付けると、使用されるモデルにはタイトルフィールドとコンテンツフィールドがあり、その最も一般的な単語はhow changeでした。 、重み付けされた単語を確認します(範囲はクエリとして機能するため、valuesを使用できます またはvalues_list 数値であるランクと類似性を確認するために、重み付きの単語を表示してベクトルオブジェクトを表示できます)、重みが割り当てられているが、分割された単語の組み合わせ:「perfil」と「cambi」が見つかりましたが、見つかりませんでした'cambiar'または'como';ただし、すべてのモデルには「lorem ipsun ...」と同じテキストが含まれており、それらが全体で重みBの場合、その文のすべての単語が含まれていました。これで、検索はフィールドの内容に基づいて行われ、検索を構成する言語以外のものをフィルタリングすると結論付けます。

    とはいえ、ここではすべてに使用するコードを示します。

    まず、データベースを有効にするために必要な範囲でトリグラムを使用する必要があります。

    from django.db import migrations
    from django.contrib.postgres.operations import UnaccentExtension, TrigramExtension
    
    class Migration(migrations.Migration):
    
        initial = True
    
        dependencies = [
        ]
    
        operations = [
          ...
          TrigramExtension(),
          UnaccentExtension(),
    
        ]
    

    postgresから移行するためのインポート操作 パッケージを作成し、任意のファイル移行から実行します。

    次のステップは、質問のコードを変更して、2番目が失敗した場合に、フィルターがクエリの1つを返すようにすることです。

    def get_queryset(self):
            search_query = SearchQuery(self.request.GET.get('q', ''))
    
            vector = SearchVector(
                'name',
                weight='A',
                config=settings.SEARCH_LANGS[settings.LANGUAGE_CODE],
            ) + SearchVector(
                'content',
                weight='B',
                config=settings.SEARCH_LANGS[settings.LANGUAGE_CODE],
            )
    
            if self.request.user.is_authenticated:
                queryset = Article.actives.all()
            else:
                queryset = Article.publics.all()
    
            return queryset.annotate(
              rank=SearchRank(vector, search_query)
              similarity=TrigramSimilarity(
                  'name', search_query
                ) + TrigramSimilarity(
                  'content', search_query
                ),
            ).filter(Q(rank__gte=0.3) | Q(similarity__gt=0.3)).order_by('-rank')[:20]
    

    上記のコードの問題は、クエリが次々に浸透することでした。選択した単語が2つの検索のいずれにも表示されない場合、問題はさらに大きくなります。 Qを使用します ORを使用してフィルタリングするオブジェクト 2つのうちの一方が目的の値を返さない場合は、もう一方を所定の位置に送信するようにコネクタを使用します。

    これで十分ですが、最新バージョンのDjangoによって提供されるこの新しい利点のほとんどを説明するために、これらの重みとトリグラマがどのように機能するかについての詳細な説明を歓迎します。



    1. AlpineLinux上のOracle

    2. Oracleデータベースで特定の列名のテーブルを検索しますか?

    3. SQLServerの一時テーブルのスコープ

    4. JAVAでjdbcTemplateのSQLクエリのタイプを判別する方法は?