新闻搜索

浪尽此生 提交于 2019-11-28 12:18:29

一、搜索功能分析

  思考:如果我们要做一个通过关键词搜索文章的功能,需要搜索哪些字段,以及使用什么技术方案?

搜索字段:

  1,字段

  2,内容

  3,作者

技术方案:

  1,mysql的模糊查询%like%

    1,优点:实现起来简单

    2,缺点:数据量比较大的情况下,查询效率极低

  2,全文检索引擎

    1,优点:专业的全文检索引擎,效率高

    2,缺点:实现起来比较复杂

选择使用全文检索引擎,自行实现django框架和全文检索引擎的代码比较麻烦,选用django的

第三方包djangohaystack。它支持多钟全文检索引擎,本项目选择最流行的全文检索引擎之一

elasticsearch

 

二、elasticsearch介绍

  elasticsearch原理:http://developer.51cto.com/art/201904/594615.htm

三、docker介绍

  1.docker介绍与安装

    ~介绍

      1,什么是docker?

        ~简化创建,部署,运行应用程序的一个工具

        ~打包应用程序所需的库和依赖环境

        ~精简的虚拟机

  2.为什么使用docher?

    流行、方便、强大

  3.docker  vs 虚拟机

    体积更小、运行更快、集成扩展更好

  4.docker架构

    ~架构

      ~客户端

      ~守护进程

      ~仓库 

    ~docker对象

      ~镜像  精简linux  

      ~容器

      ~服务

    ~docker Hub

    安装

    官方安装文档:https://www.docker.com/

    lsb_release -a   #查看系统信息 

 

五、新闻搜索功能实现

  1,业务流程分析

    判断是否传递查询参数q

    如果没有传递q,则直接返回热门新闻数据

    如果没有传递,则返回查询结果

  2,接口设计

    1.接口说明:

    类目          说明

    请求方法        GET

    url定义         /news/search/

    参数格式        查询参数

    2.参数说明:

    参数名      类型    是否必须    描述

    q        字符串     否     查询的关键字

    page      整数      否      页码

    3.返回结果:

    搜索页面html

 

1.创建haystack数据模型

news/search_indexes 文件代码

  

from haystack import indexesfrom .models import Newsclass NewsIndex(indexes.SearchIndex, indexes.Indexable):    """    这个模型的作用类似于django的模型,它告诉haystack哪些数据会被    放到查询返回的模型对象中,以及通过哪些字段进行索引和查询    """    text = indexes.CharField(document=True, use_template=True)    id = indexes.CharField(model_attr='id')    title = indexes.CharField(model_attr='title')    digest = indexes.CharField(model_attr='digest')    content = indexes.CharField(model_attr='content')    image_url = indexes.CharField(model_attr='image_url')    def get_model(self):        """        返回建立索引的模型        :return:        """        return News    def index_queryset(self, using=None):        """        返回要建立索引的数据查询集        :param using:        :return:        """        return self.get_model().objects.filter(is_delete=False)2,创建索引数据模版  templates/search/indexes/news/news_text.txt 文件  
  {{ object.title }}  {{ object.digest }}  {{ object.content }}  {{ object.author.username }}
3,创建索引

虚拟机进入项目根目录

运行命令:python manage.py -h

python manage.py rebuild_index

 

 代码:

news/templatetags/news_template_filters.py 

from django import templateregister = template.Library()@register.filter()def page_bar(page):    page_list = []    if page.number != 1:        page_list.append(1)    if page.number - 3 > 1:        page_list.append('...')    if page.number - 2 > 1:        page_list.append(page.number - 2)    if page.number - 1 > 1:        page_list.append(page.number -1)    page_list.append(page.number)    if page.paginator.num_pages > page.number + 1:        page_list.append(page.number + 1)    if page.paginator.num_pages > page.number + 2:        page_list.append(page.number + 2)    if page.paginator.num_pages > page.number + 3:        page_list.append('...')    if page.paginator.num_pages != page.number:        page_list.append(page.paginator.num_pages)    return page_listapps/news/views.py 代码
class NewsSearchView(SearchView):    """    新闻搜索视图    url: /news/search/    """    # 配置搜索模板文件    template_name = 'news/search.html'    def get(self, request, *args, **kwargs):        # 1. 获取查询参数        query = request.GET.get('q')        if not query:            # 2. 如果没有查询数            # 返回热门新闻            hot_news = HotNews.objects.select_related('news__tag').only('news__title', 'news__image_url', 'news_id', 'news__tag__name').filter(is_delete=False).order_by('priority', '-news__clicks')            # 分页            paginator = Paginator(hot_news, settings.HAYSTACK_SEARCH_RESULTS_PER_PAGE)            try:                page = paginator.get_page(int(request.GET.get('page')))            except Exception as e:                page = paginator.get_page(1)            return render(request, self.template_name, context={                'page': page,                'query': query            })        else:            # 3. 如果有怎么办            return super().get(request, *args, **kwargs)    def get_context_data(self, *args, **kwargs):        """        在context中添加变量page        :param args:        :param kwargs:        :return:        """        context = super().get_context_data(*args, **kwargs)        if context['page_obj']:            context['page'] = context['page_obj']        return context

 

 

 

 

 

          

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!