• django集成es


    前提介绍

    在此版本下,es自动与mysql或其他数据库,进行数据同步(修改,删除.新增),update并不会自动同步

    1. 准备模拟数据,安装json-server(不安装也可以.本文没有安装)

    json-server的安装https://www.jianshu.com/p/920d73fc32de

    1. # 本文借鉴
    2. https://www.jianshu.com/p/920d73fc32de
    3. # 安装(windows上安装),以管理员身份打开cmd
    4. npm install -g json-server
    5. # 测试安装成功
    6. json-server -h
    7. # 在D盘新建一个文件夹JsonServer
    8. # 进入JsonServer文件夹,初始化
    9. npm init
    10. # 在JsonServer文件夹里面新建db.json,用于接口数据
    11. {
    12. "news": [
    13. {
    14. "id":1,
    15. "title":"Tesla's Autopilot, other driver assists are in a regulatory grey zone",
    16. "content":"Filed under: Government/Legal,Tesla,Safety,Technology Continue reading Tesla's Autopilot, other driver assists are in a regulatory grey zone Tesla's Autopilot, other driver assists are in a regulatory grey zone originally appeared on Autoblog on Sat, 24 Apr"
    17. },
    18. {
    19. "id":2,
    20. "title":"‘A Bunch of People Will Probably Die’ at Onset of Mars Colonisation, Musk Cautions",
    21. "content":"The Silicone Valley mogul has candidly outlined the pitfalls of potential trips to the red planet, as his brainchild SpaceX has been going to great lengths to make commercial tourism on Mars possible one day."
    22. },
    23. {
    24. "id":3,
    25. "title":"IRS says to do this one thing to get the biggest possible tax refund",
    26. "content":"In a normal year, one in which the country wasn't dealing with the catastrophic public health and financial impacts of a global pandemic, tax season would..."
    27. }
    28. ]
    29. }
    30. # 安装依赖模块,安装完成会发现多了两个文件:
    31. npm install json-server --save
    32. # 修改配置文件
    33. 打开package.json文件,将scripts进行修改,如下:
    34. "scripts": {
    35. "json:server": "json-server --watch db.json"
    36. },
    37. # 完成之后,输入命令,运行:
    38. npm run json:server
    39. # 访问
    40. http://localhost:3000/news

    2.django集成es

    需要环境(文章中有requirements,无需担心)

    django-elasticsearch-dsl==7.2.0
    django-elasticsearch-dsl-drf==0.22

    1. python3.6.8
    2. django==3.2
    3. djangorestframework==3.12.4
    4. elasticsearch-dsl==7.3.0
    5. django-elasticsearch-dsl==7.2.0
    6. django-elasticsearch-dsl-drf==0.22

    环境安装

    1. # 创建一个虚拟环境
    2. # 安装Djangg3.2
    3. pip3 install django==3.2 -i https://pypi.douban.com/simple/
    4. # 创建一个app news
    5. # 安装依赖环境
    6. pip3 install -r requirements.txt -i https://pypi.douban.com/simple

    requirements

    1. asgiref==3.3.4
    2. certifi==2020.12.5
    3. chardet==4.0.0
    4. Django==3.2
    5. django-cors-headers==3.7.0
    6. django-debug-toolbar==3.2.1
    7. django-discover-runner==1.0
    8. django-elasticsearch-dsl==7.2.0
    9. django-elasticsearch-dsl-drf==0.22
    10. django-froala-editor==3.2.2
    11. django-ipware==3.0.2
    12. django-nine==0.2.4
    13. django-redis==4.12.1
    14. django-rest-elasticsearch==0.4.2
    15. django-role-permissions==3.1.1
    16. django-webpack-loader==0.7.0
    17. djangorestframework==3.12.4
    18. elasticsearch==7.12.0
    19. elasticsearch-dsl==7.3.0
    20. Faker==8.1.0
    21. idna==2.10
    22. ipaddress==1.0.23
    23. Pillow==8.2.0
    24. python-dateutil==2.8.1
    25. pytz==2021.1
    26. redis==3.5.3
    27. requests==2.25.1
    28. six==1.15.0
    29. sqlparse==0.4.1
    30. text-unidecode==1.3
    31. typing-extensions==3.7.4.3
    32. urllib3==1.26.4

    # settings.py进行配置

    1. INSTALLED_APPS = [
    2. 'django.contrib.admin',
    3. ...
    4. 'rest_framework',
    5. 'django_elasticsearch_dsl',
    6. 'django_elasticsearch_dsl_drf',
    7. ]
    8. ELASTICSEARCH_DSL = {
    9. 'default': {
    10. 'hosts': 'localhost:9200'
    11. },
    12. }

    # 在 news app 下的 models.py:

    1. from django.db import models
    2. # Create your models here.
    3. class ElasticNews(models.Model):
    4. title = models.CharField(max_length=100)
    5. content = models.TextField()

    # 在 news app 的 admin.py 中进行如下的修改

    本文用法

    1. from django.contrib import admin
    2. # Register your models here.
    3. from news.models import *
    4. admin.site.register(ElasticNews)

    admin的第二种用法 

        list_display = []  显示跟添加字段无关
        list_filter = []  
        search_fields = [] 
        readonly_fields = []
        filter_horizontal = []

    1. from django.contrib import admin
    2. from .models import *
    3. @admin.register(Book)
    4. class BookAdmin(admin.ModelAdmin):
    5. """Book admin."""
    6. list_display = ('title', 'price', 'publication_date')
    7. search_fields = ('title',)
    8. # 多选字段
    9. filter_horizontal = ('authors', 'tags',)
    10. @admin.register(Author)
    11. class AuthorAdmin(admin.ModelAdmin):
    12. """Author admin."""
    13. list_display = ('name', 'email',)
    14. search_fields = ('name',)
    15. @admin.register(Publisher)
    16. class PublisherAdmin(admin.ModelAdmin):
    17. """Publisher admin."""
    18. list_display = ('name',)
    19. search_fields = ('name',)
    20. @admin.register(Tag)
    21. class TagAdmin(admin.ModelAdmin):
    22. """Tag admin."""
    23. list_display = ('title',)
    24. search_fields = ('title',)

    # news app 下创建一个叫做 documents.py 的文件:

    1. from django_elasticsearch_dsl import (
    2. Document,
    3. fields,
    4. Index,
    5. )
    6. from .models import ElasticNews
    7. # 创建索引
    8. PUBLISHER_INDEX = Index('elastic_news')
    9. # 索引配置
    10. PUBLISHER_INDEX.settings(
    11. number_of_shards=1,
    12. number_of_replicas=0
    13. )
    14. # 创建映射及字段类型
    15. @PUBLISHER_INDEX.doc_type
    16. class NewsDocument(Document):
    17. id = fields.IntegerField(attr='id')
    18. fielddata = True
    19. title = fields.TextField(
    20. fields={
    21. 'keyword': {
    22. 'type': 'keyword',
    23. }
    24. }
    25. )
    26. content = fields.TextField(
    27. fields={
    28. 'keyword': {
    29. 'type': 'keyword',
    30. }
    31. },
    32. )
    33. # 配置模型
    34. class Django(object):
    35. model = ElasticNews

    # News app 下创建一个叫做 serializsers.py 的文件:

    1. import json
    2. from .models import ElasticNews
    3. from django_elasticsearch_dsl_drf.serializers import DocumentSerializer
    4. from .documents import *
    5. from rest_framework import serializers
    6. # 创建序列化器
    7. class NewsDocumentSerializer(DocumentSerializer):
    8. # 同样支持重写字段
    9. title = serializers.SerializerMethodField()
    10. class Meta(object):
    11. """Meta options."""
    12. # 模型
    13. model = ElasticNews
    14. # 索引
    15. document = NewsDocument
    16. # 控制序列化的字段
    17. fields = ('id', 'title', 'content')
    18. # fields = '__all__'
    19. # 自定义返回数据
    20. def get_title(self, obj):
    21. # print('dddddddddddddd', obj.price)
    22. return obj.price

    # 在 News app 下的 views.py 文件,以便能在访问页面时生产相应的 Elasticsearch 文档

    1. from django.http import JsonResponse
    2. import requests
    3. import json
    4. from news.models import *
    5. from .documents import *
    6. from .serializers import *
    7. from django_elasticsearch_dsl_drf.filter_backends import (
    8. FilteringFilterBackend,
    9. CompoundSearchFilterBackend
    10. )
    11. from django_elasticsearch_dsl_drf.viewsets import DocumentViewSet
    12. from django_elasticsearch_dsl_drf.filter_backends import (
    13. FilteringFilterBackend,
    14. OrderingFilterBackend,
    15. )
    16. # 写入es的函数
    17. def generate_random_data():
    18. # 安装JsonServer,
    19. """
    20. url = 'http://localhost:3000/news'
    21. r = requests.get(url)
    22. payload = json.loads(r.text)
    23. count = 1
    24. print("---------------------payload--------------", payload)
    25. print("type of payload is: ", type(payload))
    26. for data in payload:
    27. # print("title: ", data['title'])
    28. # print("content: ", data['content'])
    29. ElasticNews.objects.create(
    30. title=data['title'],
    31. content=data['content']
    32. )
    33. """
    34. # 不安装JsonServer,自己构建数据
    35. payload = [
    36. {'title': '洞c内', 'content': 'casac', 'price': '666'},
    37. {'title': '传s说', 'content': 'cas', 'price': '99'},
    38. {'title': '啊不错', 'content': 'casa', 'price': '966'}
    39. ]
    40. for data in payload:
    41. ElasticNews.objects.create(
    42. **data
    43. )
    44. # 写入es
    45. def index(request):
    46. # es与mysql自动同步数据
    47. generate_random_data()
    48. return JsonResponse({'status': 200})
    49. # return HttpResponse("Hello, the world")
    50. # 用来读数据进行搜索并排序的一个 view
    51. class PublisherDocumentView(DocumentViewSet):
    52. # mapping
    53. document = NewsDocument
    54. # 序列化器
    55. serializer_class = NewsDocumentSerializer
    56. lookup_field = 'id'
    57. fielddata = True
    58. filter_backends = [
    59. FilteringFilterBackend,
    60. OrderingFilterBackend,
    61. CompoundSearchFilterBackend,
    62. ]
    63. # 在全文中搜索范围的字段配置(模糊匹配)
    64. # Define filtering fields
    65. filter_fields = {
    66. 'title': 'title',
    67. 'content': 'content',
    68. # 'id': 'id',
    69. }
    70. # Define search fields
    71. search_fields = (
    72. # 'id',
    73. 'title',
    74. 'content',
    75. )
    76. # Define ordering fields
    77. ordering_fields = {
    78. 'id': None,
    79. }
    80. # 指定默认顺序
    81. ordering = ('id', 'content')
    82. # 支持多个参数
    83. multi_match_search_fields = (
    84. 'title',
    85. 'content',
    86. )
    87. # 测试
    88. def update_data(request):
    89. # 群更新会触发
    90. # query = ElasticNews.objects.all()
    91. # for item in query:
    92. # item.title = 'uuuuuuuuuuu'
    93. # item.save()
    94. # 单更新会触发
    95. # obj = ElasticNews.objects.filter(id=3).first()
    96. # obj.title = '刘亚萍99999999999'
    97. # obj.save()
    98. # create会触发
    99. # ElasticNews.objects.create(title='cas', content='222', price='85')
    100. # ElasticNews.objects.create(title='多对多', content='cas', price='85')
    101. ElasticNews.objects.create(title='cas', content='csa', price='85')
    102. # ElasticNews.objects.create(title='cas2', content='lcas', price='85')
    103. # 删除
    104. # ElasticNews.objects.filter(id=4).delete()
    105. # update不会触发es与mysql同步,也不会触发信号post_save
    106. # ElasticNews.objects.filter(id=1).update(title='圆梦去', content='222', price='85')
    107. return JsonResponse({'status': 200})

    # 修改 ulrpatterns

    1. from django.contrib import admin
    2. from django.urls import path
    3. from news.views import *
    4. urlpatterns = [
    5. path('admin/', admin.site.urls),
    6. path('search/', PublisherDocumentView.as_view({'get': 'list'})),
    7. path('add/', index),
    8. path('update/', update_data),
    9. ]

    # 我们使用如下的命令来创建 Elasticsearch 索引 mapping:

    1. python manage.py makemigrations
    2. python manage.py migrate
    3. # 执行这一句,如果存在索引,就删除重新构建,不执行也可以,保证当前配置的索引唯一即可
    4. python manage.py search_index --rebuild

     # 访问 

    1. http://127.0.0.1:8000/
    2. http://127.0.0.1:8000/search/

    查询使用 

    1. class Meta:
    2. """Meta options."""
    3. # 即模型对象返回的记录结果集是按照这个字段排序的。
    4. ordering = ["id"]
    5. # 使用过滤排序
    6. # 所有字段中搜索cas
    7. http://127.0.0.1:8000/search/?search=cas
    8. # 要在特定字段 中搜索术“cas”
    9. # 例子:要在字段title中搜索“cas”
    10. http://127.0.0.1:8000/search/?search=title:cas
    11. # 搜索多个术语 二者或的关系
    12. http://127.0.0.1:8000/search/?search=cas&search=洞c内
    13. # 要在特定字段 搜索多个术语 二者或的关系
    14. http://127.0.0.1:8000/search/?search=title:cas&search=content:卡车
    15. # 按单个字段筛选文档
    16. http://127.0.0.1:8000/search/?title=cas
    17. # 或搜索(不支持中文)
    18. http://127.0.0.1:8000/search/?title__in=cas__cas2
    19. # and(不支持中文)
    20. http://127.0.0.1:8000/search/?title=cas&content=csa
    21. # 按单个字段的单词部分筛选文档(正则搜索)
    22. http://127.0.0.1:8000/search/?title__wildcard=*内
    23. # 按字段对文档进行排序(升序
    24. http://127.0.0.1:8000/search/?search=content:cas&ordering=id
    25. # 按字段对文档进行排序(降序)
    26. http://127.0.0.1:8000/search/?search=content:cas&ordering=-id
    27. # 按多个字段对文档进行排序
    28. 如果要按多个字段排序,请使用多个排序查询参数。在下面的示例中,文档将首先按字段排序(降序),然后按字段排序(升序)
    29. http://127.0.0.1:8080/search/publisher/?ordering=-country&ordering=city

  • 相关阅读:
    【五分钟Paper】基于参数化动作空间的强化学习
    配置编译设置
    【全志T113-S3_100ask】14-1 linux采集usb摄像头实现拍照(FFmpeg、fswebcam)
    python从小白到大师-第一章Python应用(七)应用领域与常见包-自动化办公PPT
    Layui快速入门之第二节布局容器(固定宽度与完整宽度)
    高性能同轴高清 ISP芯片XS5012A参数
    分类算法-逻辑回归与二分类
    [python]basemap后安装后hello world代码
    Android开发基础——常用控件的使用方法
    HTTP协议中的Cookie和Session
  • 原文地址:https://blog.csdn.net/qq_52385631/article/details/126412961