python-django框架中使用docker和elasticsearch配合实现搜索功能

注意:系统环境为Ubuntu18

一、docker安装

  0:如果之前有安装过docker使用以下命令卸载:

sudo apt-get remove docker docker-engine docker.io containerd runc

  docker安装官网参考:

https://docs.docker.com/install/linux/docker-ce/ubuntu/

  1:首先更新apt

sudo apt-get update

  2:添加证书安装包以允许apt通过HTTPS:

sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common

  3:添加docker官方密钥

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

  4:添加仓库

sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

  5:安装docker ce

sudo apt-get install docker-ce docker-ce-cli containerd.io

  6:测试

sudo docker run hello-world

  7:添加当前系统用户到docker用户组

sudo usermod -aG docker 用户名  

 

docker 拓展命令:

  docker images :查看所有启动成功的镜像

  docker ps -a :查看所有

  docker logs 容器id :查看容器日志 

  docker 如果启动容器失败,就先删除容器,删除目录,再次执行安装。

 

二、使用docker安装Elasticsearch

1:获取镜像

docker image pull delron/elasticsearch-ik:2.4.6-1.0  

 如果pull拉取很慢可以从我的百度云中下载,然后传到Linux系统中然后使用docker命令导入

链接:https://pan.baidu.com/s/1zXBR_uHSFxK5xNxklGV1pQ
提取码:96iw  

docker load -i elasticsearch-ik-2.4.6_docker.tar

 查看本地仓库是否有这个镜像

docker images
或
docker image ls

  将下载的elasticsearch.zip上传到Linux系统中的家目录,然后解压。在目录中的elasticsearch/config/elasticsearch.yml第54行更改IP地址为0.0.0.0,端口改为8002,默认为9002

  解压命令:

unzip elasticsearch.zip

 

2:创建docker容器并运行

 根据拉取到本地的镜像创建容器,需要将elasticsearch/config配置文件所在目录修改为你自己的路径

docker run -dti --network=host --name=elasticsearch -v /home/上面上传后解压出来的文件路径地址/elasticsearch/config:/usr/share/eleaticsearh/config delron/elasticsearch-ik:2.4.6-1.0

  查看是否创建成功,如果STATUS为Up则创建成功

docker container ls -a 或 docker ps -a

  python-django框架中使用docker和elasticsearch配合实现搜索功能_第1张图片

 测试 curl 127.0.0.1:8002

python-django框架中使用docker和elasticsearch配合实现搜索功能_第2张图片

 

3:进入项目的虚拟环境中,安装以下包

pip install django-haystack
pip install elasticsearch==2.4.1

  

4:在django项目配置,在settings.py文件中加入下面配置。

4-1:在INSTALLED_APPS节点中注册haystack

INSTALLED_APPS = [
    ...
    'haystack',
    ...
]

4-2:加入配置 

# 建立连接
ELASTICSEARCH_DSL = {
  'default':{
    'host':'127.0.0.1:8002'  
  },
}
# 配置Haystack HAYSTACK_CONNECTIONS = { 'default': { 'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine', 'URL': 'http://127.0.0.1:8002/', # 此处为elasticsearch运行的服务器ip地址,端口号固定为9200 'INDEX_NAME': 'mysite', # 指定elasticsearch建立的索引库的名称 }, } # 当添加、修改、删除数据时,自动生成索引,当数据库改变时候,会自动更新索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor' 
# 每页显示多少条数据
HAYSTACK_SEARCH_RESULTS_PER_PAGE = 20

 

5:建立索引

 在需要创建索引的实体中创建search_indexes.py(文件名固定写法)

  python-django框架中使用docker和elasticsearch配合实现搜索功能_第3张图片

5-1:search_indexes.py文件内容如下:

 

from haystack import indexes
from .models import News  # 导入模型类


# 建索引类
# 模型名称+Index(固定的)
class NewsIndex(indexes.SearchIndex, indexes.Indexable):
    '''
    News索引数据库模型
    '''
    # 这个主要是使用5-2来建立索引
    text = indexes.CharField(document=True, use_template=True)
    # 以下是为了在使用时 news.id 如果没有写就需要news.object.id
    id = indexes.IntegerField(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 News

    def index_queryset(self, using=None):
        '''
        返回要建立索引的数据查询集
        :param using:
        :return:
        '''

        return set.get_model().objects.filter(is_delete=False, tag_id=1)
        # return set.get_model().objects.filter(is_delete=False,tag_id=[1,2,3,4,5])

  

5-2:创建模板

# 需要在templates文件夹中创建一个search/indexes/app名称/模型名称小写_text.txt文件(固定结构)

  python-django框架中使用docker和elasticsearch配合实现搜索功能_第4张图片

news_text.txt内容为:需要建立的索引

python-django框架中使用docker和elasticsearch配合实现搜索功能_第5张图片

 

6:生成索引

通过xshell进入项目进入虚拟环境执行

python manage.py rebuild_index

  python-django框架中使用docker和elasticsearch配合实现搜索功能_第6张图片

 

7: 分页搜索接口/方法

7-1

from haystack.views import SearchView as _SearchView
from .models import News  # 导入模型类
from .models import HotNews
from mysite import setttings
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.shortcuts import render
from django.views import View


class SearchView(_SearchView):
    # 模板文件
    template = 'news/search.html'

    # 重写响应方式,如果请求参数为空,返回模型News的热门新闻数据,否则根据参数q搜索相关数据
    def create_response(self):
        kw = self.request.GET.get('q', '')
        if not kw:
            show_all = True
            hot_news = HotNews.objects.select_related(
                'News'
            ).only(
                'news__title',
                'news__image_url',
                'news__id'
            ).filter(
                is_delete=False
            ).order_by(
                'priority',
                '-news__clicks'
            )
            paginator = Paginator(hot_news, setttings.HAYSTACK_SEARCH_RESULTS_PER_PAGE)
            try:
                page = paginator.page(int(self.request.GET.get('page', 1)))
            except PageNotAnInteger:
                # 如果参数page的数据类型不是整数,则返回第一页数据
                page = paginator.page(1)
            except EmptyPage:
                # 用户访问的页数大于实际的页数,则返回最后一页的数据
                page = paginator.page(paginator.num_pages)
            return render(self.request, self.template, locals())
        else:
            show_all = False
            qs = super(SearchView, self).create_response()
            return qs

7-2:在app中的urls中设置url 

path('search/',view.SearchView(),name='search')

7-3:前端部分代码

         
{% if not show_all %}

搜索结果 {{ paginator.num_pages }}

    {% for one_news in page.object_list %}
  • {% highlight one_news.title with query %}

    {% highlight one_news.digest with query %}

    {{ one_news.object.tag.name }} {{ one_news.object.update_time }} {% highlight one_news.object.author.username with query %}
  • {% endfor %}
{% else %}

热门推荐

    {% for one_hotnews in page.object_list %}
  • {{ one_hotnews.news.title }}

    {{ one_hotnews.news.digest }}

    {{ one_hotnews.news.tag.name }} {{ one_hotnews.update_time }} {{ one_hotnews.news.author.username }}
  • {% endfor %}
{% endif %} {# 分页导航 #}
{{ page.paginator.count }}条 {# 上一页的URL地址 #} {% if page.has_previous %} {% if query %} {% else %} {% endif %} {% endif %} {# 列出所有的URL地址 #} {% for num in page.paginator.page_range|slice:":10" %} {% if num == page.number %} {{ page.number }} {% else %} {% if query %} {{ num }} {% else %} {{ num }} {% endif %} {% endif %} {% endfor %} {# 如果页数大于10,则打两点 #} {% if page.paginator.num_pages > 10 %} .. {% if query %} {{ page.paginator.num_pages }} {% else %} {{ page.paginator.num_pages }} {% endif %} {% endif %} {# 下一页的URL地址 #} {% if page.has_next %} {% if query %} {% else %} {% endif %} {% endif %}

  

7-4:高亮及分页样式

/* === current index start === */
#pages {
	padding: 32px 0 10px;
}

.page-box {
	text-align: center;
    /*font-size: 14px;*/
}

#pages a.prev, a.next {
	width: 56px;
	padding: 0
}

#pages a {
	display: inline-block;
	height: 26px;
	line-height: 26px;
	background: #fff;
	border: 1px solid #e3e3e3;
	text-align: center;
	color: #333;
	padding: 0 10px
}

#pages .sel {
	display: inline-block;
	height: 26px;
	line-height: 26px;
	background: #0093E9;
	border: 1px solid #0093E9;
	color: #fff;
	text-align: center;
	padding: 0 10px
}

.highlighted{
    color:coral;
    mso-ansi-font-weight: bold;
}
/* === current index end === */

  

8:效果图

 python-django框架中使用docker和elasticsearch配合实现搜索功能_第7张图片

 

转载于:https://www.cnblogs.com/wendj/p/10979960.html

你可能感兴趣的:(python-django框架中使用docker和elasticsearch配合实现搜索功能)