一、基于数据库的模糊查询

这是一种很不理想的查询方法,并且对数据库的压力很大,查询的效率低下,我一般不建议采用这种查询方式。

例如:想要查询models.py中MyNew类的字段(title)标题

代码如下

def search(request):
    keyword = request.GET.get("keyword")  # 获取前端传回来的查询关键字
    newList = MyNew.objects.filter(title__icontains=keyword)  # MyNew中models.py 中title标题的查询
    newName = "关于" + "\"" + keyword + "\"" + "的搜索结果"
    return render(request, search.html)

二、基于haystack的全文高级搜索

django-haystack是一个专门提供搜索功能的Django第三方应用,它支持Solr

RlasticSearch、Whoosh、Xapian等多种搜索引擎,配合著名的中文自然语言处理库jieba分词,就可以实现高级查询。

这里使用Whoosh引擎和jieba分词。

安装这些包

pip install whoosh django-haystack jieba

安装好之后在项目的setting.py中做简单的配置,将django-haystack加入到INSTALLED_APPS中

INSTALLED_APPS = [
    'django.contrib.admin',
    ...
    ...
     # 添加查找应用
    'haystack',
    ]

然后在setting.py文件末尾添加如下配置

# 配置全文高级搜索
HAYSTACK_CONNECTIONS = {
    'default': {
        # 此处为默认的WhooshEngine,后面会修改它,因此把它注释掉
        # 'ENGINE': 'haystack.backends.whoosh_cn_backend.WhooshEngine',
        'ENGINE': 'newsApp.whoosh_cn_backend.WhooshEngine',
        'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
    }
}
HAYSTACK_SEARCH_RESULTS_PER_PAGE = 5   # 查询显示时每5页为分页
# 添加此项,当数据库改变时,会自动更新索引,非常方便
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

完成上述配置后接下来就是要告诉django-haystack使用哪些数据建立索引以及如何存放索引,如果要对newsApp 应用下的新闻内容进行全文检索,具体做法是在newsApp应用下建立一个search_indexes.py文件,然后添加代码如下:

from haystack import indexes
from .models import Mynew


class MyNewIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)  # document=True一般约定此字段名为text

    # 使用的模型
    def get_model(self):
        return Mynew

    # 返回的数据
    def index_queryset(self, using=None):
        return self.get_model().objects.all()

django-haystack规定如果要对某个App下的数据进行全文检索,就要在该APP下创建一个search_indexes.py文件,然后创建一个XX Indexable类(XX为含有被索引数据的模型,如这里是MyNew)。创建索引是因为索引就像是一本书的目录,可以为读者快速的导航和查找。

在这里每个索引必须有且只有一个字段为document=True,这代表了django-haystack和搜索引擎将使用此字段的内容作为索引。例如MyNew的title和description字段,这样就可以通过title和description内容来检索MyNew数据了。数据模板路径为:

templates/search/indexes/newsApp/MyNew_text.txt

 

创建的MyNew_text.text文件,编辑其中内容如下:

{{ object.title }}
{{ object.description }}

 这个模板的作用是对MyNew中title和description两个字段建立索引,当检索的时候会对这两个字段做全文索引匹配,然后将匹配的结果排序后返回。

接下来配置URL

urlpatterns = [
    path('admin/', xadmin.site.urls),
    ...
    ...
    path('search/', include('haystack.urls')),    # 添加haystack搜索的路径


]

编写newList.html文件的表单action属性

<div class="col-md-7 hidden-xs model-details-title-search">
     <form method="get" action="{% url 'haystack_search' %}">
           {% csrf_token %}
           <div class="input-group">
           <input type="text" name="q" class="form-control" placeholder="请输入关键词" required/>
            <span class="input-group-btn">
            <input type="submit" class="btn btn-default" value="查询"/>
            </span>
             </div>
       </form>
 </div>

注意输入文本框中name的属性,name="q",否则django-haystack默认的视图处理函数无法解析出数据。

这里使用的是Whoosh作为搜索引擎,但是在django-haystack中Whoosh分词器默认是英文分词器,因此需要把分词器换成jieba中文分词器。在haystack安装目录的backends文件夹中找到whoosh_cn_backend.py文件,并将其复制到newsApp文件夹下,然后找到如下代码进行修改。

                schema_fields[field_class.index_fieldname] = TEXT(
                    stored=True,
                    analyzer=StemmingAnalyzer(),
                    field_boost=field_class.boost,
                    sortable=True,
                )

                改为

                schema_fields[field_class.index_fieldname] = TEXT(
                    stored=True,
                    analyzer=ChineseAnalyzer(),
                    field_boost=field_class.boost,
                    sortable=True,
                )

 这样就将英文分词器改为中文分词器了,在头部引入

from jieba.analyse import ChineseAnalyzer

至此,整一个搜索框架的搭建就完成了。最后运行下述命令重建索引文件完成内容索引。

python manage.py rebulid_index

查看搜索效果。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐