2016-08-01 2 views
7

내 모델에서 텍스트를 검색하고 db 쿼리로 동시에 필터링해야합니다. 예를 들어db 쿼리로 haystack 결과를 필터링하는 방법

는 :

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 

그래서 나는 사용자 및 전체 텍스트 검색을 통해 텍스트의 모든 MyModel 개체를 필터링 할. 이와 같은 매끄러운은 :

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

또는

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

물론 원하는 DB 쿼리는 훨씬 더 복잡 할 수 있습니다.

나는 주요 결함으로 몇 가지 가능한 솔루션을 모두 볼 : 장고에

  1. 만들기 교차 : QS에서 ID를 추출하고 그 반대의 경우도 마찬가지 SQS 필터 또는에서 사용할. 문제 : 성능. 우리는 페이지 매김을 사용하여 회피 할 수 있으며 주어진 페이지와 그 전임자에 대해서만 교차를 수행 할 수 있습니다. .이 경우 우리는 총 개수 (

  2. 색인 모든 M2M 관련 분야 문제 잃게 : 성능, (나는) DB가 훨씬 더 같은 쿼리를 할 것으로 판단 기능을 복제를 등 주석

  3. 같은 DB-기능 건초 더미를 사용하지 마십시오 (MySQL 용 이동 또는 posgresql 내장 전체 텍스트 검색.

를 내가 뭔가를 분명 그리워 생각합니다. 케이스는 매우 일반적인 것 같다. 기존의 솔루션이 있습니까?

+1

"교차점"변수에 어떤 데이터가 있어야합니까? MyModel과 MyModelIndex 객체를 포함해야합니까? 또는 당신은 단지 하나 또는 다른 것을 필요로합니까? 달성하고자하는 것을 설명 할 수 있다면 도움이 될만한 컨텍스트는 없습니다. –

+0

@TitusP : 제 교차로에서 쿼리 세트 또는 검색 결과를 원합니다. 필자는 모든 MyModel 개체를 사용자별로 필터링하고 전체 텍스트 검색을 통해 텍스트로 필터링하려고합니다. – Nik

+0

어떤 건초 더미 엔진을 사용하십니까? –

답변

1

에서 장군 하나의 쿼리만으로는 문제를 해결할 수 없습니다. 예를 들어 ElasticSearch를 검색 백엔드 엔진으로 사용하고 Django 모델을 MySQL로 사용하는 경우 MySQL과 ElasticSearch가 통신하여 단일 공통 쿼리를 생성하는 방법이 없습니다.

그러나 Django 모델과 Haystack 백엔드 엔진에 일반적인 SQL 데이터베이스를 사용하는 경우 해결 방법이 있어야합니다. 쿼리를 구문 분석하고 사용 가능한 모델을 필터링하는 사용자 정의 haystack 엔진을 만들어야합니다.

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 

그리고 settings.py에서

:

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

어떤 연결에 따라

예를 들어, SimpleSearchBackend의 동작을 수정하기 위해, 당신이 오직 할 필요가있는 search 방법을 패치한다 백엔드를 사용하면 필요한 패치는 물론 다르지만 구현하기가 너무 어렵지 않을 것으로 판단됩니다.

관련 문제