Django REST Elasticsearch

基本用法

Django REST Elasticsearch提供了集成Django REST FrameworkElasticsearch的簡(jiǎn)便方法。該庫(kù)使用Elasticsearch DSL庫(kù)(elasticsearch-dsl-py)它是官方低級(jí)客戶端的高級(jí)庫(kù)。

讓我們看一下使用Django REST Elasticsearch構(gòu)建一個(gè)簡(jiǎn)單應(yīng)用程序的快速示例。在這個(gè)例子中,我們將構(gòu)建一個(gè)簡(jiǎn)單的博客系統(tǒng)。

要求

  • Django REST Framework 3.5及更高版本
  • elasticsearch-dsl> = 5.0.0,<7.0.0(Elasticsearch 5.x)
安裝
pip install django-rest-elasticsearch
創(chuàng)建模型

首先,我們創(chuàng)建一個(gè)模型。

class Blog(models.Model):
    title = models.CharField(_('Title'), max_length=1000)
    created_at = models.DateTimeField(_('Created at'), auto_now_add=True)
    body = models.TextField(_('Body'))
    tags = ArrayField(models.CharField(max_length=200), blank=True, null=True)
    is_published = models.BooleanField(_('Is published'), default=False)

    def __str__(self):
        return self.title
在Elasticsearch中創(chuàng)建映射

然后,我們必須圍繞我們的Django模型創(chuàng)建一個(gè)類似于模型的包裝器。

class BlogIndex(DocType):

    pk = Integer()
    title = Text(fields={'raw': Keyword()})
    created_at = Date()
    body = Text()
    tags = Keyword(multi=True)
    is_published = Boolean()

    class Meta:
        index = 'blog'

我們需要在Elasticsearch中創(chuàng)建映射。為此,您可以通過調(diào)用init類方法直接創(chuàng)建映射:

BlogIndex.init()

文檔生命周期文檔中,您可以找到有關(guān)如何手動(dòng)使用文檔的完整說明。

添加,更新或刪除新數(shù)據(jù)時(shí)使索引可更新

我們希望在ElasticSearch中擁有一致的數(shù)據(jù),這就是我們?cè)诟哪P椭械娜魏蝺?nèi)容時(shí)需要?jiǎng)?chuàng)建,更新或刪除文檔的原因。最好的方法是添加一個(gè)Django信號(hào)調(diào)度程序。在添加信號(hào)之前,讓我們創(chuàng)建一個(gè)序列化器來創(chuàng)建,更新和刪除elasticsearch文檔。

from rest_framework_elasticsearch.es_serializer import ElasticModelSerializer
from .models import Blog
from .search_indexes import BlogIndex

class ElasticBlogSerializer(ElasticModelSerializer):
    class Meta:
        model = Blog
        es_model = BlogIndex
        fields = ('pk', 'title', 'created_at', 'tags', 'body', 'is_published')

在我們需要?jiǎng)?chuàng)建signals.py文件并添加此代碼之后:

from django.db.models.signals import pre_save, post_delete
from django.dispatch import receiver
from .serializers import Blog, ElasticBlogSerializer

@receiver(pre_save, sender=Blog, dispatch_uid="update_record")
def update_es_record(sender, instance, **kwargs):
    obj = ElasticBlogSerializer(instance)
    obj.save()

@receiver(post_delete, sender=Blog, dispatch_uid="delete_record")
def delete_es_record(sender, instance, *args, **kwargs):
    obj = ElasticBlogSerializer(instance)
    obj.delete(ignore=404)
簡(jiǎn)單的django REST框架搜索視圖

最后,讓我們創(chuàng)建一個(gè)簡(jiǎn)單的搜索視圖,查找按標(biāo)簽過濾的所有帖子,并按標(biāo)題中的單詞進(jìn)行搜索:

from elasticsearch import Elasticsearch, RequestsHttpConnection
from rest_framework_elasticsearch import es_views, es_pagination, es_filters
from .search_indexes import BlogIndex

class BlogView(es_views.ListElasticAPIView):
    es_client = Elasticsearch(hosts=['elasticsearch:9200/'],
                              connection_class=RequestsHttpConnection)
    es_model = BlogIndex
    es_filter_backends = (
        es_filters.ElasticFieldsFilter,
        es_filters.ElasticSearchFilter
    )
    es_filter_fields = (
        es_filters.ESFieldFilter('tag', 'tags'),
    )
    es_search_fields = (
        'tags',
        'title',
    )

就是這樣,我們可以開始使用它了。

http://example.com/blogs/api/list?search=elasticsearch
http://example.com/blogs/api/list?tag=opensource
http://example.com/blogs/api/list?tag=opensource,aws

分頁(yè)

分頁(yè)響應(yīng)的示例

class BlogView(es_views.ListElasticAPIView):
    es_client = Elasticsearch(hosts=['elasticsearch:9200/'],
                              connection_class=RequestsHttpConnection)

    es_pagination_class = es_pagination.ElasticLimitOffsetPagination

    es_model = BlogIndex
    es_filter_backends = (
        es_filters.ElasticFieldsFilter,
        es_filters.ElasticSearchFilter
    )
    es_filter_fields = (
        es_filters.ESFieldFilter('tag', 'tags'),
    )
    es_search_fields = (
        'tags',
        'title',
    )

排序

排序示例

class BlogView(es_views.ListElasticAPIView):
    es_client = Elasticsearch(hosts=['elasticsearch:9200/'],
                              connection_class=RequestsHttpConnection)

    es_pagination_class = es_pagination.ElasticLimitOffsetPagination

    es_filter_backends = (
        es_filters.ElasticFieldsFilter,
        es_filters.ElasticSearchFilter,
        es_filters.ElasticOrderingFilter,
    )
    es_ordering_fields = (
        "created_at",
        ("title.raw", "title")
    )
    es_filter_fields = (
        es_filters.ESFieldFilter('tag', 'tags'),
    )
    es_search_fields = (
        'tags',
        'title',
    )

https://github.com/myarik/django-rest-elasticsearch

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • # Python 資源大全中文版 我想很多程序員應(yīng)該記得 GitHub 上有一個(gè) Awesome - XXX 系列...
    小邁克閱讀 3,120評(píng)論 1 3
  • 2018年悄然過去,在這臨近春節(jié)的日子,總有那么一些行業(yè)的人默默堅(jiān)守在工作的一線,他們工作辛苦,不遠(yuǎn)萬里在祖國(guó)的另...
    抓住世界的尾巴閱讀 178評(píng)論 0 0
  • 今天 達(dá)武旦 一段舍不得 一個(gè)人走的旅程 提前走了—— 帶著你給我的 白色帆布袋 香薰和燈盞 ——《陰翳禮贊> 寫...
    達(dá)武旦閱讀 135評(píng)論 0 1
  • 文 / 芹菜 今年國(guó)慶節(jié)后,我開始密集的寫作。到今天,剛好40天,粗略的計(jì)算了一下,竟然寫了8萬字。有時(shí)一天三篇,...
    芹菜qincai閱讀 655評(píng)論 0 6
  • 背景:最近連續(xù)幾周被項(xiàng)目中的APNS實(shí)現(xiàn)所折騰,服務(wù)器和客戶端都存在坑,服務(wù)器升級(jí)導(dǎo)致一堆bug,修復(fù)完后客戶端這...
    文藝氣息的工程師閱讀 437評(píng)論 0 0

友情鏈接更多精彩內(nèi)容