python - How to filter haystack results with db query -


i need text-search across model , filter db queries @ same time.

for example:

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 

so want filter mymodel objects user , text via full-text search. smth these:

qs = mymodel.objects.filter(users=request.user) sqs = mymodelindex.objects.filter(text=request.get['q']) intersection = some_magic_function(qs, sqs) 

or

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

of course desired db queries more complicated.

i see possible solutions, major flaws:

  1. make intersection in django: extract ids qs , use them in sqs filter or vice versa. problem: performance. can workaround itby using pagination , intersection given page , predecessors. in case lose total count (

  2. index m2m related fields. problem: performance, duplicate functionality (i believe db such queries better), db-features such annotations etc.

  3. do not use haystack ( go mysql or posgresql built-in full-text search.

i believe miss obvious. case seems quite common. there conventional solution?

in general case, it's (probably) not possible solve problem using 1 query. instance, if using elasticsearch search backend engine , mysql django models, there no way mysql , elasticsearch communicate produce single, common query.

however, there should workaround if using common sql database django models , haystack backend engine. have create custom haystack engine parse query , filter available models.

for example, modify behaviour of simplesearchbackend, need patch search method:

class customsimplesearchbackend(haystack.backends.simplesearchbackend):      def search(self, query_string, **kwargs):         ...         if query_string:             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 

and in settings.py:

haystack_connections = {     'default': {         'engine': 'myapp.backends.customsimpleengine',     }, } 

depending on connection backend use, required patch different of course, suspect should not hard implement.


Comments