5

値を持ついくつかのオブジェクトを除外するには、ヘイスタック検索が必要ですpublished=False。これまでに管理した方法は、exclude(published=True)次のように追加することです。

class MymodelIndex(indexes.RealTimeSearchIndex, indexes.Indexable):
    def get_queryset(self):
        return Mymodel.objects.all().exclude(published=False)

それは期待どおりに機能しますが、問題は./manage.py rebuild_index、新しいオブジェクトがデータベースに追加されるたびに必要になることです。

他に何も実行する必要なく、どうすればそれを作成できますか?

ノート:

Haystack のインデックスは多くのモデルで機能するため、次のようになります。

search = (
    SearchQuerySet().filter(content=term)
)

1 つのモデルだけでなく、さまざまな種類のオブジェクトを返します。

ありがとう

4

4 に答える 4

3

私は最近、これに似たようなことをしなければなりませんでした。これを行う他の方法が見つかりませんでした。

最初に、多くのモデルで動作する Haystack の問題に対処するため、フィルターはすべての一致を返します。

Haystack は、アプリ名とモデル名に等しい django_ct と呼ばれるインデックスを作成するプロパティを使用して、バックグラウンドでモデル フィルタリングを処理します。私の特定のケースでは、のように見えましたdjango_ct='books.Title'

次のようにしてフィルタリングを試すことができます

SearchQuerySet.filter(content=term, django_ct='app.Model')

しかし、それがそのように機能するかどうかはわかりません。私の特定のケースでは、とにかく生の検索を行う必要があったため、フィルタリングを直接追加することができました。

sqs = SearchQuerySet()
sqs = sqs.raw_search(u'(title:(%s)^500 OR author:"%s"^400 OR "%s"~2 OR (%s)) AND (django_ct:books.Title)' % term)

SearchQuerySet取得方法に関係なく、インデックスを更新せずに追加のフィルタリングを実行したいことを取得したら、独自のコードでそれを行う必要があります。

# each item in a queryset has a pk property to the model instance it references
pks = [item.pk for item in list(sqs)] # have to wrap sqs in a list otherwise it causes problems

# use those pks to create a standard django queryset object
results = Model.objects.filter(pk__in=pks)

# Now you can do any additional filtering like normal
results = results.exclude(published=False)

もちろん、最後の 2 つのクエリを結合することもできます。明示的にするために分割しただけです。

それほど多くのコードではありませんが、さまざまな理由で機能するまでに長い時間がかかりました。うまくいけば、それはあなたを助けます.

于 2013-03-12T23:24:18.350 に答える
2

haystack 2.4.0 以降haystack.exceptions.SkipDocument、簡単に除外できる個々のレコードをスキップするためにレイズできます。index_queryset

https://github.com/django-haystack/django-haystack/releases/tag/v2.4.0

于 2016-07-20T17:44:25.707 に答える
0

@SI Eric のおかげで、私は答えを見つけることができました。これもハックですが、機能します。

search = (
    SearchQuerySet().filter(content=term)
)

search_list = search[:]
unpublished_Mymodels = Mymodel.objects.filter(published=False)

for match in search_list:
    try:
        if match.model_name == 'Mymodel':
            if match._get_object() in unpublished_Mymodels:
                search_list.remove(match)
    except:
        pass

search = search_list
于 2013-03-13T00:45:50.333 に答える