如何使用db查询过滤haystack结果

时间:2016-08-01 13:42:20

标签: python django django-haystack

我需要在我的模型中进行文本搜索并同时使用db查询进行过滤。

例如:

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对象。 Smth喜欢这些:

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']}
)

当然,期望的数据库查询可能要复杂得多。

我看到了一些可能的解决方案,都存在重大缺陷:

  1. 在django中创建交集:从qs中提取id并在sqs过滤器中使用它们,反之亦然。问题:表现。我们可以通过使用分页来解决它,并且仅对给定页面及其前身进行交集。在这种情况下,我们会失去总数(

  2. 索引所有m2m相关字段。问题:性能,重复功能(我相信db会更好地执行此类查询),db-features(如注释等)。

  3. 不要使用haystack(Go for mysql或posgresql内置全文搜索。

  4. 我相信我会错过一些明显的东西。案例似乎很常见。有传统的解决方案吗?

1 个答案:

答案 0 :(得分:1)

在一般情况下,它(可能)只能使用一个查询来解决您的问题。例如,如果您使用ElasticSearch作为搜索后端引擎而MySQL用于django模型,则MySQL和ElasticSearch无法通信以生成单个常见查询。

但是,如果您为Django模型和Haystack后端引擎使用通用SQL数据库,则应该有一个解决方法。您必须创建一个自定义干草堆引擎来解析查询并过滤可用的模型。

例如,要修改SimpleSearchBackend的行为,您需要做的就是修补search方法:

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

在settings.py中:

 private InfiniteViewPager pager = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

pager = (InfiniteViewPager) findViewById(R.id.pager);
FragmentManager fragmentManager = getSupportFragmentManager();
pager.setAdapter(new MyAdapter(fragmentManager));
pager.setPageTransformer(true, new CubeOutTransformer());
pager.setCurrentItem(2);

根据您使用的连接后端,所需的补丁当然会有所不同,但我怀疑它不应该太难实现。