如何在Python中使用Haystack和Elasticsearch索引和查询数据

草垛

Haystack是一个Python库,可为Django提供模块化搜索。 它具有一个API,可为不同的搜索后端提供支持,例如Elasticsearch,Whoosh,Xapian和Solr。

弹性搜索

Elasticsearch是一种流行的Lucene搜索引擎,能够进行全文本搜索,它使用Java开发。

Google搜索使用与索引数据相同的方法,这就是为什么仅用几个关键字就可以很容易地检索任何信息的原因,如下所示。

弹性搜索和Google
安装Django Haystack和Elasticsearch

第一步是在您的计算机上本地启动和运行Elasticsearch。 Elasticsearch需要Java,因此您需要在计算机上安装Java。

我们将按照Elasticsearch网站上的说明进行操作。

下载Elasticsearch 1.4.5 tar,如下所示:

curl -L -O https://download.elastic.co/elasticsearch/elasticsearch/elasticsearch-1.4.5.tar.gz

提取如下:

tar -xvf elasticsearch-1.4.5.tar.gz

然后,它将在当前目录中创建一批文件和文件夹。 然后,我们进入bin目录,如下所示:

cd elasticsearch-1.4.5/bin

如下所示启动Elasticsearch。

./elasticsearch

要确认它是否已成功安装,请访问http://127.0.0.1:9200/ ,您应该会看到类似的内容。

{
  "name" : "W3nGEDa",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "ygpVDczbR4OI5sx5lzo0-w",
  "version" : {
    "number" : "5.6.3",
    "build_hash" : "1a2f265",
    "build_date" : "2017-10-06T20:33:39.012Z",
    "build_snapshot" : false,
    "lucene_version" : "6.6.1"
  },
  "tagline" : "You Know, for Search"
}

确保您还安装了干草堆。

pip install django-haystack

让我们创建我们的Django项目。 我们的项目将能够为银行中的所有客户建立索引,从而仅需几个搜索字词就可以轻松地搜索和检索数据。

django-admin startproject Bank

该命令创建的文件为Django项目提供配置。

让我们为客户创建一个应用程序。

cd Bank

python manage.py startapp customers
settings.py配置

为了使用Elasticsearch索引可搜索的内容,我们需要在项目的settings.py文件中为haystack定义一个后端settings.py 。 我们将使用Elasticsearch作为后端。

HAYSTACK_CONNECTIONS是必需的设置,应如下所示:

HAYSTACK_CONNECTIONS = {
    'default': {
        'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
        'URL': 'http://127.0.0.1:9200/',
        'INDEX_NAME': 'haystack',
    },
}

settings.py ,我们还将将干草堆和客户添加到installed apps的列表中。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'haystack',
    'customer'
]
创建模型

让我们为客户创建一个模型。 在customers/models. py ,添加以下代码。

from __future__ import unicode_literals

from django.db import models


# Create your models here.
customer_type = (
    ("Active", "Active"),
    ("Inactive", "Inactive")
)


class Customer(models.Model):
    id = models.IntegerField(primary_key=True)
    first_name = models.CharField(max_length=50, null=False, blank=True)
    last_name = models.CharField(
        max_length=50, null=False, blank=True)
    other_names = models.CharField(max_length=50, default=" ")
    email = models.EmailField(max_length=100, null=True, blank=True)
    phone = models.CharField(max_length=30, null=False, blank=True)
    balance = models.IntegerField(default="0")
    customer_status = models.CharField(
        max_length=100, choices=customer_type, default="Active")
    address = models.CharField(
        max_length=50, null=False, blank=False)

    def save(self, *args, **kwargs):
        return super(Customer, self).save(*args, **kwargs)

    def __unicode__(self):
        return "{}:{}".format(self.first_name, self.last_name)

像这样在admin.py注册您的Customer模型:

from django.contrib import admin
from .models import Customer

# Register your models here.

admin.site.register(Customer)
创建数据库和超级用户

应用您的迁移并创建一个管理员帐户。

python manage.py migrate
python manage.py createsuperuser

运行服务器并导航到http:// localhost:8000 / admin / 。 现在,您应该可以在那里看到您的客户模型。 继续并在管理员中添加新客户。

索引数据

为了索引我们的模型,我们首先创建一个SearchIndexSearchIndex对象确定应在搜索索引中放置哪些数据。 每种类型的模型都必须具有唯一的searchIndex

SearchIndex对象是干草堆确定应在搜索索引中放置哪些数据并处理数据流的方式。要构建SearchIndex ,我们将从indexes.SearchIndexindexes.Indexable继承,定义我们想要的字段存储我们的数据,并定义一个get_model方法。

让我们创建的CustomerIndex对应于我们的Customer模型。 在客户应用目录中创建文件search_indexes.py ,并添加以下代码。

from .models import Customer
from haystack import indexes


class CustomerIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.EdgeNgramField(document=True, use_template=True)
    first_name = indexes.CharField(model_attr='first_name')
    last_name = indexes.CharField(model_attr='last_name')
    other_names = indexes.CharField(model_attr='other_names')
    email = indexes.CharField(model_attr='email', default=" ")
    phone = indexes.CharField(model_attr='phone', default=" ")
    balance = indexes.IntegerField(model_attr='balance', default="0")
    customer_status = indexes.CharField(model_attr='customer_status')
    address = indexes.CharField(model_attr='address', default=" ")

    def get_model(self):
        return Customer

    def index_queryset(self, using=None):
        return self.get_model().objects.all()

EdgeNgramField是在草堆的字段SearchIndex防止不正确匹配时的两个不同的字的部分一起捣碎。

它允许我们使用autocomplete功能进行查询。 当我们开始查询数据时,将使用自动完成功能。

document=True表示要在其中进行搜索的主要字段。 另外, text字段中的use_template=True允许我们使用数据模板来构建将要建立索引的文档。

让我们在客户模板目录中创建模板。 在search/indexes/customers/customers_text.txt ,添加以下内容:

{{object.first_name}}
{{object.last_name}}
{{object.other_names}}
重新索引数据

现在我们的数据在数据库中,是时候将其放入搜索索引了。 为此,只需运行./manage.py rebuild_index 。 您将获得处理和放置在索引中的模型总数。

Indexing 20 customers

另外,您可以使用RealtimeSignalProcessor ,它会自动为您处理更新/删除。 要使用它,请在settings.py文件中添加以下内容。

HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
查询数据

我们将使用搜索模板和Haystack API来查询数据。

搜索模板

将干草堆网址添加到您的URLconf中。

url(r'^search/', include('haystack.urls')),

让我们创建搜索模板。 在templates/search.html ,添加以下代码。

{% block head %}
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>

{% endblock %}
{% block navbar %}
 <nav class="navbar navbar-default">
  <div class="container">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="#">HOME</a>
    </div>
    <div class="collapse navbar-collapse" id="myNavbar">
      <ul class="nav navbar-nav navbar-right">
        <li><input type="submit" class="btn btn-primary" value="Add Customer">  </li>
    </ul>
    </div>
  </div>
</nav>
{% endblock %}
{% block content %}
<div class="container-fluid bg-3 text-center">  
<form method="get" action="." class="form" role="form">
        {{ form.non_field_errors }}
        <div class="form-group">
                {{ form.as_p }}
        </div>
        <div class="form-group">
            <input type="submit" class="btn btn-primary" value="Search">
        </div>

        {% if query %}
            <h3>Results</h3>
              
        <div class="container-fluid bg-4 text-left">    
                <div class="row">
    
                    {% for result in page.object_list %}
                       
                <div class="col-sm-4">
                  <div class="thumbnail">
                             
                    <div class="form-group">
                        <p>First name : {{result.first_name}} </p>
                    </div>

                    <div class="form-group">
                        <p>Last name : {{result.last_name}} </p>
                        
                    </div>

                    <div class="form-group">
                        <p>Balance : {{result.balance}} </p>
                    </div>
                    <div class="form-group">
                        <p>Email : {{result.email}} </p>
                    </div>
                    <div class="form-group">
                        <p>Status : {{result.customer_status}} </p>
                    </div>
                  </div>
                </div>
                {% empty %}
                    
                   <p style="text-center">No results found.</p>
                    {% endfor%}
                </div>
        </div>   
           
        {% endif %}
</form>
</div>

{% endblock %}

page.object_listSearchResult对象的列表,它使我们能够获取单个模型对象,例如result.first_name

您完整的项目结构应如下所示:

项目目录结构

现在运行服务器,转到127.0.0.1:8000/search/ ,并进行如下所示的搜索。

在本地服务器上运行搜索

Albert的搜索将给出所有名为Albert客户的结果。 如果没有客户的名字是Albert,那么查询将给出空结果。 随意使用自己的数据。

干草堆API

Haystack具有SearchQuerySet类,该类旨在使执行搜索和迭代结果变得容易且一致。 大多数SearchQuerySet API都熟悉Django的ORM QuerySet

customers/views.py ,添加以下代码:

from django.shortcuts import render
from rest_framework.decorators import (
    api_view, renderer_classes,
)
from .models import Customer
from haystack.query import SearchQuerySet

from rest_framework.response import Response
# Create your views here.


@api_view(['POST'])
def search_customer(request):
    name = request.data['name']
    customer = SearchQuerySet().models(Customer).autocomplete(
        first_name__startswith=name)

    searched_data = []
    for i in customer:
        all_results = {"first_name": i.first_name,
                       "last_name": i.last_name,
                       "balance": i.balance,
                       "status": i.customer_status,
                       }
        searched_data.append(all_results)

    return Response(searched_data)

autocomplete是执行自动完成搜索的快捷方式。 它必须针对EdgeNgramFieldNgramField字段运行。

在上面的Queryset ,我们使用contains方法来过滤搜索,以仅检索包含定义的字符的结果。 例如, Al将仅检索包含Al的客户的详细信息。 请注意,结果将仅来自customer_text.txt file定义的字段。

查询结果

除了contains字段查找之外,还有其他可用于执行查询的字段,包括:

  • 内容
  • 包含
  • 精确
  • gt
  • te
  • lt
  • 以。。开始
  • 以。。结束
  • 范围
  • 模糊

结论

在社交媒体,医疗保健,购物和其他行业的任何特定时刻,都会产生大量数据。 这些数据大部分都是非结构化和分散的。 Elasticsearch可用于将这些数据处理和分析成一种易于理解和使用的形式。

Elasticsearch还被广泛用于内容搜索,数据分析和查询。 有关更多信息,请访问HaystackElasticsearch网站。

翻译自: https://code.tutsplus.com/articles/how-to-index-and-query-data-with-haystack-and-elasticsearch-in-python--cms-29492

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值