2016-08-01 19 views
7

Modelimde metin araması yapmalı ve aynı zamanda db sorguları ile filtrelemeliyim. Örneğinds sorgusuyla haystack sonuçlarını filtreleme

:

class MyModel(models.Model): 
    text = models.TextField() 
    users = models.ManyToMany(User) 

class MyModelIndexIndex(indexes.SearchIndex, indexes.Indexable): 
    text = indexes.CharField(document=True, model_attr='text') 

    def get_model(self): 
     return MyModel 

Yani kullanıcı tarafından VE tam metin arama üzerinden bazı metnin bütün MyModel nesneleri filtrelemek istiyorum. Bu gibi Smth:

qs = MyModel.objects.filter(users=request.user) 
sqs = MyModelIndex.objects.filter(text=request.GET['q']) 
intersection = some_magic_function(qs, sqs) 

veya

intersection = some_other_magic_function(
    qs_kwargs={'users': request.user}, 
    sqs_kwargs={'text': request.GET['q']} 
) 

Tabii istenen db sorguları çok daha karmaşık olabilir.

I büyük kusurları ile bazı olası çözüm, tüm bkz Django

  1. Marka kesişim: qs gelen kimlikleri elde ve tersi OKS filtre veya bunları kullanmak. Sorun: performans. Sayfalama kullanarak geçici bir çözüm bulabiliriz ve yalnızca belirli bir sayfa ve öncülleri için kesişim yapabiliriz. . Bu durumda biz toplam sayısı (

  2. Endeksi bütün m2m ilgili alanlar Sorun kaybetmek: performans, (I) db daha iyi gibi sorguları yapacağına inanıyorum işlevselliği çoğaltmak, vb ek açıklamalar

  3. olarak db-özellikler samanlık kullanmayın (mysql için gidin veya PostgreSQL'de yerleşik tam metin araması.

ben belirgin bir şey kaçırmak inanıyoruz. Vaka oldukça yaygın olarak görünüyor. geleneksel çözüm var mı?

+1

"Kesişim" değişkeninizde hangi verilerin olması gerekir? MyModel yanı sıra MyModelIndex nesneleri içermesi gerekiyordu? Yoksa sadece birine mi ihtiyacın var? Neyi başarmaya çalıştığınızı anlatabilirseniz yardımcı olabilirsiniz, olduğu gibi bir bağlam yoktur. –

+0

@TitusP: Kesişimimde ya queryset ya da searchresultset istiyorum. Örneğimde tüm MyModel nesnelerini kullanıcı ve metne göre tam metin araması ile filtrelemek istiyorum. – Nik

+0

Hangi saman motorunu kullanıyorsunuz? –

cevap

1

yılında Genel durumda, (muhtemelen) sadece bir sorgu kullanarak sorununuzu çözmek mümkün değildir. Örneğin, ElasticSearch'ü arama arka uç motoru ve django modelleri için MySQL kullanıyorsanız, MySQL ve ElasticSearch'ün tek bir ortak sorgu oluşturmak için iletişim kurmasının bir yolu yoktur. Ancak, Django modelleriniz ve Haystack arka uç motorunuz için ortak bir SQL veritabanı kullanıyorsanız, bununla ilgili bir çözüm bulunmalıdır. Üste | Sorguyu ayrıştırabilecek ve mevcut modelleri filtreleyecek özel bir haystack motoru oluşturmanız gerekir.

class CustomSimpleSearchBackend(haystack.backends.SimpleSearchBackend): 

    def search(self, query_string, **kwargs): 
     ... 
     if query_string: 
      for model in models: 
       ... 
       if 'users' in kwargs: 
        qs = qs.filter(users=kwargs['users']) 
       ... 

class CustomSimpleEngine(haystack.backends.BaseEngine): 
    backend = CustomSimpleSearchBackend 
    query = haystack.backends.simple_backend.SimpleSearchQuery 

Ve settings.py içinde

:

HAYSTACK_CONNECTIONS = { 
    'default': { 
     'ENGINE': 'myapp.backends.CustomSimpleEngine', 
    }, 
} 

hangi bağlantı bağlı

Örneğin, SimpleSearchBackend davranışını değiştirmek için yapmanız gereken tek şey search yöntemi yama edilir Kullandığınız arka uç, gerekli yama elbette farklı olacak, ama uygulamak için çok zor olmamalıdır şüpheleniyorum.