Django的__search与__icontains之间的区别

时间:2014-04-02 01:30:50

标签: django full-text-search

我最近开始学习Django,所以请原谅我,如果这对你来说太新手了。

我在Django中实现了一个搜索功能。我在MySQL DB全文索引中创建了一个字段,然后在我的书模型中使用了一个字段:search_keywords,其中我基本上存储了所有单词,包括书的标题和内容。然后我的搜索功能做了类似的事情:

search_keyword = self.request.GET.get('keywords')
    if search_keyword:
        # '*' is added for cases where user enters only part of the keyword
        qs = qs.filter(keywords__search=search_keyword + '*')

但是如果我的搜索查询是'intro',我知道有一个单词/术语如'test.introduction'(如果这个术语只是'引入'那么它可以正常工作),上述方法不起作用。

然后当我尝试这样做时:

        qs = qs.filter(keywords__icontains=search_keyword)

找到'test.introduction'等。

所以我开始想知道为什么会这样。 “__search”仅适用于全字搜索吗?我知道'__icontains'的情况有意义(不区分大小写并包含单词的一部分),但为什么要在DB中创建全文索引,这样我们可以在Django中使用'__search'?这是速度优势吗(例如,在搜索大量文本的情况下?或者我在这里完全遗漏了什么?

1 个答案:

答案 0 :(得分:5)

区别在于在数据库上执行的SQL查询...我个人更喜欢“__icontains”因为所有数据库都支持,而“__search”仅适用于mysql(as django docs)(还支持Django中的PostgreSQL≥1.10 - 见documentation)。

查看每种方法的查询:

使用__search

>>> str(Contact.objects.filter(first_name__search='john').query)

'SELECT `contact_contact`.`id`, `contact_contact`.`title`, `contact_contact`.`first_name`, `contact_contact`.`last_name`, `contact_contact`.`user_id`, `contact_contact`.`role_id`, `contact_contact`.`organization_id`, `contact_contact`.`dob`, `contact_contact`.`email`, `contact_contact`.`notes`, `contact_contact`.`create_date` FROM `contact_contact` WHERE MATCH (`contact_contact`.`first_name`) AGAINST (john IN BOOLEAN MODE)'

使用__icontains

>>> str(Contact.objects.filter(first_name__icontains='john').query)

'SELECT `contact_contact`.`id`, `contact_contact`.`title`, `contact_contact`.`first_name`, `contact_contact`.`last_name`, `contact_contact`.`user_id`, `contact_contact`.`role_id`, `contact_contact`.`organization_id`, `contact_contact`.`dob`, `contact_contact`.`email`, `contact_contact`.`notes`, `contact_contact`.`create_date` FROM `contact_contact` WHERE `contact_contact`.`first_name` LIKE %john% '