2016-06-16 13 views
7

django 1.10で検索を行い、トライグラム検索でユーザーランク検索が必要です。我々は、クエリを得ることができない彼らの間で結合し、djangoでランク検索とトリグラムを組み合わせる1.10

def get_queryset(self): 
     search = self.request.GET.get('text', '') 
     vector = SearchVector('name',weight='A', 
      config=settings.SEARCH_LANGS[ 
       settings.LANGUAGE 
      ], 
      ) + SearchVector(
      'content', 
      weight='B', 
      config=settings.SEARCH_LANGS[ 
       settings.LANGUAGE 
      ], 
      ) 
     query = SearchQuery(search) 
     return Article.objects.annotate(
      rank=SearchRank(
       vector, 
       query 
       ), 
      similarity=TrigramSimilarity(
       'name', search 
       ) + TrigramSimilarity(
       'content', search 
       ), 
      ).filter(
      rank__gte=0.3 
      ).filter(
      similarity__gt=0.3 
      ).order_by(
      '-similarity' 
      )[:20] 

しかし、このコードは、使用トライグラム、私たちの避難所の問題もなく、任意のクエリを返しませんが、:

私たちのコードはこれです。

django 1.10でトライグラムとランク検索を組み合わせるにはどうすればいいですか?

答えて

10

検索の重み付けの仕組みをより完全に理解するために調査しました。

documentsによれば、フィールドに応じて重みを割り当てることができ、重みを割り当てることもできます。同様に、trigramsを使用して類似性または距離でフィルタリングすることができます。

しかし両者を用いて、さらに調査の一例を指定しないことが理解さも重みが働くようにはるか。

少しロジックを教えてくれる、我々はすべてのランク0意志すべてに共通の単語を求める場合には、類似性が範囲よりはるかに変化すること、しかし範囲の値を低下させる傾向があります。

さて、テキスト検索は、限り我々は理解し、それはあなたが構成で配置されている言語の場合よりもさらにフィルタするフィールドに含まれるテキストに基づいて行われます。例は、タイトルを入れて、使用されるモデルは、(加重単語を見直しタイトルフィールドとその最も一般的な単語how changeがあっコンテンツフィールドを、持っていたクエリとしての機能の範囲ということですので、我々はvaluesまたはvalues_listはランクと類似性を確認するために使用することができ、我々は、重みが割り当てられ、分割された単語の組み合わせ: 'perfil'と 'cambi'を発見したが、 'cambiar'または 'como'を見つけなかったことを見出した。 ;しかし、すべてのモデルには、「lorem ipsun ...」と同じテキストが含まれていました。それらが全体で重みがBならば、その文のすべての単語が含まれていました。これで、検索の設定は、フィールドの内容に基づいて行われ、検索を構成する言語以上のものをフィルタリングすると結論づけます。

つまり、ここでは私たちがすべてのために使用するコードを示します。 postgresパッケージからの移行のための

from __future__ import unicode_literals 

from django.db import migrations, models 
import django.db.models.deletion 
from django.contrib.postgres.operations import UnaccentExtension 
from django.contrib.postgres.operations import TrigramExtension 

class Migration(migrations.Migration): 

    initial = True 

    dependencies = [ 
    ] 

    operations = [ 
     ... 
     TrigramExtension(), 
     UnaccentExtension(), 

    ] 

インポート操作および任意のファイル移行から実行:

まず、我々はTrigram構築にデータベースを有効にするために必要な範囲を使用する必要があります。

次のステップは、第二が失敗した場合、フィルタはquerysのいずれかを返すように問題のコードを変更することである:上記のコードに問題が次々に照会を浸出した

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 
      ) + TrigramSimilarity(
       'content', search 
      ), 
     ).filter(Q(rank__gte=0.3) | Q(similarity__gt=0.3)).order_by('-rank')[:20] 

、及び選択された単語が2つの検索のいずれにも表示されない場合、問題はより大きくなります。 Qオブジェクトを使用してORコネクタを使用してフィルタを適用し、2つのうちの一方が目的の値を返さない場合は、もう一方を送信します。

これで十分ですが、Djangoの最新バージョンが提供するこの新しい利点のほとんどを解明するために、これらの重みと三角関数がどのように機能するかを歓迎しています。

+0

見つけた解決策をお寄せいただきありがとうございます。 – Private

関連する問題