zoukankan      html  css  js  c++  java
  • Django rest framework 使用haystack对接Elasticsearch

    Elasticsearch 介绍

    ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

    首先安装 java 环境

    https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
    

      

    配置java环境变量

    (1)新建->变量名"JAVA_HOME",变量值"C:Javajdk1.8.0_05"(即JDK的安装路径) 
    (2)编辑->变量名"Path",在原变量值的最后面加上“;%JAVA_HOME%in;%JAVA_HOME%jrein” 
    (3)新建->变量名“CLASSPATH”,变量值“.;%JAVA_HOME%lib;%JAVA_HOME%libdt.jar;%JAVA_HOME%lib ools.jar”

     下载  elasticsearch-rtf

    https://github.com/medcl/elasticsearch-rtf

     启动 elasticsearch

     进入bin 下执行

    elasticsearch.bat

    drf中使用

    Haystack为Django提供了模块化的搜索。它的特点是统一的,熟悉的API,可以让你在不修改代码的情况下使用不同的搜索后端(比如 Solr, Elasticsearch, Whoosh, Xapian 等等)。

    我们在django中可以通过使用haystack来调用Elasticsearch搜索引擎。

    drf-haystack官方文档: https://drf-haystack.readthedocs.io/en/latest/

    环境:django ==1.11.11

    1.首先安装相关的依赖包:(这里原作者使用的是drf-haystack,如果项目没有使用drf组件,应该选用haystack包)

    pip install drf-haystack 
    pip install elasticsearch==2.4.1
    

    2.在django项目配置文件settings.py中注册应用:  

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

    3.在django项目配置文件settings.py中指定搜索的后端:(指定使用那个搜索引擎,服务器地址的配置,索引库的名称等配置)  

    # Haystack
    HAYSTACK_CONNECTIONS = {
        'default': {
            'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
            # 端口号固定为9200
            'URL': 'http://192.168.247.128:9200/', # 此处为elasticsearch运行的服务器ip地址,端口号固定为9200
            # 指定elasticsearch建立的索引库的名称
            'INDEX_NAME': 'meiduo_mall',
            # 保存索引文件的路径
            # 'PATH': os.path.join(BASE_DIR, 'elastic_index'), # 如果搜索引擎是whoosh, 还需要设置PATH参数
        },
    }  
    # 当添加、修改、删除数据时,自动生成索引
    HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
    

      

    注意:

    HAYSTACK_SIGNAL_PROCESSOR 的配置保证了在Django运行起来后,有新的数据产生时,haystack仍然可以让Elasticsearch实时生成新数据的索引

    4 创建索引类  

    通过创建索引类,来指明让搜索引擎对哪些字段建立索引,也就是可以通过哪些字段的关键字来检索数据。

    在goods应用目录下新建一个search_indexes.py(固定的)文件,用于存放索引类。search_indexes.py 这个文件名是固定的,你需要对那个应用进行检索,就在那个应用下创建

    代码如下

    from haystack import indexes
    
    from .models import goods
    
    
    class SKUIndex(indexes.SearchIndex, indexes.Indexable):
        """
        索引类, 告诉haystack在建立数据索引的时候使用
        """
        text = indexes.CharField(document=True, use_template=True)
    
        def get_model(self):
            """把那个表建立索引"""
            return goods
    
        def index_queryset(self, using=None):
            """返回要建立索引的数据查询集"""
            return self.get_model().objects.filter()

    说明:

    在SKUIndex建立的字段,都可以借助haystack由elasticsearch搜索引擎查

    其中text字段我们声明为document=True,表名该字段是主要进行关键字查询的字段, 该字段的索引值可以由多个数据库模型类字段组成,具体由哪些模型类字段组成,我们用use_template=True表示后续通过模板来

    指明。其他字段都是通过model_attr选项指明引用数据库模型类的特定字段。

    在REST framework中,索引类的字段会作为查询结果返回数据的来源。

    5 在templates下面新建目录search/indexes/goods/goodssku_text.txt

     goods是和应用的名字对应上,而goodssku是和get_model中对象的名字(小写)对应上的

    (关于路径的定义和文件的命名的说明:templates是项目原来的html文件的目录,search是在其下新建的,名称一定,indexes名称也一定,goods是应用的名称,goodssku_text.txt 就是需要进行索引的模型类名的小写 + "_" + 索引类中定义的字段名称(text) + ".txt" )

     具体在templates/search/indexes/goods/goods_text.txt文件中定义

    {{ object.name }}
    {{ object.caption }}
    {{ object.id }}
    

    此模板指明当将关键词通过text参数名传递时,可以通过sku的name、caption、id来进行关键字索引查询。

    6 手动生成初始索引  

    python manage.py rebuild_index
    

    7.创建haystack序列化器:(返回查询到的查询集数据)

    goods/serializers.py

    from rest_framework import serializers
    from .models import SKU
    
    
    class SKUSerializer(serializers.ModelSerializer):
        """
        SKU序列化器
        """
    
        class Meta:
            model = SKU
            fields = ('id', 'name', 'price', 'default_image_url', 'comments')
    
    from drf_haystack.serializers import HaystackSerializer
    from .search_indexes import SKUIndex
    
    class SKUIndexSerializer(HaystackSerializer):
        """
        SKU索引结果数据序列化器
        """
        object = SKUSerializer(read_only=True)
    
        class Meta:
            index_classes = [SKUIndex]
            # text 由索引类进行返回, object 由序列化类进行返回,第一个参数必须是text
            fields = (
                'text',  # 用于接收查询关键字
                'object',  # 用于返回查询结果
                'id',
                'name',
                'price'
            )

     注意:fields属性的字段名与DemoIndex类的字段对应。

    8  创建视图

     goods/views.py

    from drf_haystack.viewsets import HaystackViewSet
    from .serializers import SKUIndexSerializer
    from .models import SKU
    
    class SKUSearchViewSet(HaystackViewSet):
        """
        SKU搜索
        """
        index_models = [SKU]
    
        serializer_class = SKUIndexSerializer

    这里是通过父类默认的方法进行返回了数据, 可以在视图中对数据进行筛选和处理,详细的使用方法可以去查看官方文档,drf-haystack官方文档:https://drf-haystack.readthedocs.io/en/latest/

    注意:
    • 该视图会返回搜索结果的列表数据,所以如果可以为视图增加REST framework的分页功能。
    • 我们在实现商品列表页面时已经定义了全局的分页配置,所以此搜索视图会使用全局的分页配置。

    9 定义路由

    通过REST framework的router来定义路由

    router = DefaultRouter()
    router.register('skus/search', views.SKUSearchViewSet, base_name='skus_search')
     
    ...
     
    urlpatterns += router.urls
    

    10 测试  

    http://api.meiduo.site:8000/skus/search/?text=wifi
    
    http://api.meiduo.site:8000/skus/search/?id=1
    
    http://api.meiduo.site:8000/skus/search/?name=iphone

    如果在配置完haystack并启动程序后,出现如下异常,是因为drf-haystack还没有适配最新版本的REST framework框架

     

    可以通过修改REST framework框架代码,补充_get_count函数定义即可

    文件路径 虚拟环境下的 lib/python3.6/site-packages/rest_framework/pagination.py

    def _get_count(queryset):
        """
        Determine an object count, supporting either querysets or regular lists.
        """
        try:
            return queryset.count()
        except (AttributeError, TypeError):
            return len(queryset)
    

    再次测试  

     返回的数据举例如下:

    {
        "count": 10,
        "next": "http://api.meiduo.site:8000/skus/search/?page=2&text=%E5%8D%8E",
        "previous": null,
        "results": [
            {
                "text": "华为 HUAWEI P10 Plus 6GB+64GB 钻雕金 移动联通电信4G手机 双卡双待
    wifi双天线设计!徕卡人像摄影!P10徕卡双摄拍照,低至2988元!
    9",
                "id": 9,
                "name": "华为 HUAWEI P10 Plus 6GB+64GB 钻雕金 移动联通电信4G手机 双卡双待",
                "price": "3388.00",
                "default_image_url": "http://10.211.55.5:8888/group1/M00/00/02/CtM3BVrRcUeAHp9pAARfIK95am88523545",
                "comments": 0
            },
            {
                "text": "华为 HUAWEI P10 Plus 6GB+128GB 钻雕金 移动联通电信4G手机 双卡双待
    wifi双天线设计!徕卡人像摄影!P10徕卡双摄拍照,低至2988元!
    10",
                "id": 10,
                "name": "华为 HUAWEI P10 Plus 6GB+128GB 钻雕金 移动联通电信4G手机 双卡双待",
                "price": "3788.00",
                "default_image_url": "http://10.211.55.5:8888/group1/M00/00/02/CtM3BVrRchWAMc8rAARfIK95am88158618",
                "comments": 5
            }
        ]
    }
  • 相关阅读:
    Postman使用教程
    CAD和ArcGIS转换 矢量配准
    SAP CRM Advanced search和Simple search里Max hit表现行为的差异
    SAP CRM Product simple search的启用步骤
    如何快速定位SAP CRM订单应用(Order Application)错误消息抛出的准确位置
    如何动态修改SAP CRM WebClient UI表格栏的宽度
    如何在SAP CRM WebClient UI里创建web service并使用ABAP消费
    如何处理SAP CRM Web Service错误
    如何使用SAP CRM WebClient UI实现一个类似新浪微博的字数统计器
    如何开启SAP CRM基于WORD模板创建附件的功能
  • 原文地址:https://www.cnblogs.com/crazymagic/p/10046593.html
Copyright © 2011-2022 走看看