Django:Elasticsearch搜索系统的使用

1,687 阅读2分钟

小知识,大挑战!本文正在参与「程序员必备小知识」创作活动

  • Docker install ElasticSearch
  • Django:haystack全文检索详细教程

使用Docker安装Elasticsearch及其扩展

  • 创建Docker镜像
docker run -dit --name=myubuntu es
  • 安装ElasticSearch

    • 下载
    wget https://download.elastic.co/elasticsearch/release/org/elasticsearch/distribution/tar/elasticsearch/2.4.4/elasticsearch-2.4.4.tar.gz
    
    tar -xzvf elasticsearch-2.4.4.tar.gz -C /usr/local
    cd /usr/local/elasticsearch-2.4.4
    
    • 更新ES配置
    cd conf
    
    vi elasticsearch.yml
    
    bootstrap.memory_lock: true
    index.cache.field.max_size: 50000
    index.cache.field.expire: 30m
    index.cache.field.type: soft
    
    network.host: 0.0.0.0,127.0.0.1
    
    action.disable_delete_all_indices : true
    
    • 安装启动ES
    cd ../bin
    
    //直接启动ElasticSearch
    ./elasticsearch 
    
    //或者使用后台方式进行启动
    ./elasticsearch -d
    

    通常ES会使用9200和9300端口,查看端口占用情况:

    netstat -anp|grep 9200
    

    result:

    root@192.168.*.25:/usr/local/elasticsearch-2.4.4/bin# netstat -anp|grep 9200
    tcp        0      0 192.168.*.58:9200       0.0.0.0:*               LISTEN      11135/java          
    tcp        0      0 127.0.0.1:9200          0.0.0.0:*               LISTEN      11135/java  
    
    • 安装完毕,退出和查看正在运行的容器列表
    docker exit
    
    docker container ls --all
    

使用Haystack对接Elasticsearch

  • 我们在Django中可以通过使用 haystack来调用Elasticsearch搜索引擎。
  • 安装
pip install drf-haystack
pip install elasticsearch==2.4.1
  • 注册应用
INSTALLED_APPS = [
    ...
    'haystack',
    ...
]
  • 修改配置文件settings.py
# Haystack
HAYSTACK_CONNECTIONS = {
    'default': {
        'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
        'URL': 'http://127.0.0.1:9200/',  # 此处为elasticsearch运行的服务器ip地址,端口号固定为9200
        'INDEX_NAME': 'XXXXXX',  # 指定elasticsearch建立的索引库的名称
    },
}


# 当添加、修改、删除数据时,自动生成索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

使用Elasticsearch完成商品搜索

  • 创建索引类 通过创建索引类,知名搜索引擎可以通过哪些字段的关键字来检索数据。
from haystack import indexes

from goods.models import SKU


class SKUIndex(indexes.SearchIndex, indexes.Indexable):
    """
    SKU索引数据模型类
    """
    text = indexes.CharField(document=True, use_template=True)

    def get_model(self):
        """返回建立索引的模型类"""
        return SKU

    def index_queryset(self, using=None):
        """返回要建立索引的数据查询集"""
        return self.get_model().objects.filter(is_launched=True)
  • 手动生成初始索引

    • templates目录中创建text字段使用的模板文件 具体在templates/search/indexes/goods/sku_text.txt文件中定义。
    {{ object.name }}
    {{ object.title }}
    {{ object.detail }}
    
    • 手动生成初始化索引
    python manage.py rebuild_index
    
  • 定义路由url

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

urlpatterns += router.urls
  • 创建视图
from drf_haystack.viewsets import HaystackViewSet

class SKUSearchViewSet(HaystackViewSet):
    """
    SKU搜索
    """
    index_models = [SKU]

    serializer_class = SKUIndexSerializer
    
  • 测试 使用路由进入接口测试
http://localhost:8000/skus/search/?text=测试商品
  • bug修复 haystackElasticsearch版本的匹配问题。 可以通过修改REST framework框架代码,补充_get_count函数定义即可。

文件路径 pyenv环境下的 lib/python3.9/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)