使用Python操作Elasticsearch数据索引的教程


Posted in Python onApril 08, 2015

Elasticsearch是一个分布式、Restful的搜索及分析服务器,Apache Solr一样,它也是基于Lucence的索引服务器,但我认为Elasticsearch对比Solr的优点在于:

  •     轻量级:安装启动方便,下载文件之后一条命令就可以启动;
  •     Schema free:可以向服务器提交任意结构的JSON对象,Solr中使用schema.xml指定了索引结构;
  •     多索引文件支持:使用不同的index参数就能创建另一个索引文件,Solr中需要另行配置;
  •     分布式:Solr Cloud的配置比较复杂。

环境搭建

启动Elasticsearch,访问端口在9200,通过浏览器可以查看到返回的JSON数据,Elasticsearch提交和返回的数据格式都是JSON.

>> bin/elasticsearch -f

安装官方提供的Python API,在OS X上安装后出现一些Python运行错误,是因为setuptools版本太旧引起的,删除重装后恢复正常。

>> pip install elasticsearch

索引操作

对于单条索引,可以调用create或index方法。

from datetime import datetime
from elasticsearch import Elasticsearch
es = Elasticsearch() #create a localhost server connection, or Elasticsearch("ip")
es.create(index="test-index", doc_type="test-type", id=1,
  body={"any":"data", "timestamp": datetime.now()})

Elasticsearch批量索引的命令是bulk,目前Python API的文档示例较少,花了不少时间阅读源代码才弄清楚批量索引的提交格式。

from datetime import datetime
from elasticsearch import Elasticsearch
from elasticsearch import helpers
es = Elasticsearch("10.18.13.3")
j = 0
count = int(df[0].count())
actions = []
while (j < count):
   action = {
        "_index": "tickets-index",
        "_type": "tickets",
        "_id": j + 1,
        "_source": {
              "crawaldate":df[0][j],
              "flight":df[1][j],
              "price":float(df[2][j]),
              "discount":float(df[3][j]),
              "date":df[4][j],
              "takeoff":df[5][j],
              "land":df[6][j],
              "source":df[7][j],
              "timestamp": datetime.now()}
        }
  actions.append(action)
  j += 1

  if (len(actions) == 500000):
    helpers.bulk(es, actions)
    del actions[0:len(actions)]

if (len(actions) > 0):
  helpers.bulk(es, actions)
  del actions[0:len(actions)]

在这里发现Python API序列化JSON时对数据类型支撑比较有限,原始数据使用的NumPy.Int32必须转换为int才能索引。此外,现在的bulk操作默认是每次提交500条数据,我修改为5000甚至50000进行测试,会有索引不成功的情况。

#helpers.py source code
def streaming_bulk(client, actions, chunk_size=500, raise_on_error=False,
    expand_action_callback=expand_action, **kwargs):
  actions = map(expand_action_callback, actions)

  # if raise on error is set, we need to collect errors per chunk before raising them
  errors = []

  while True:
    chunk = islice(actions, chunk_size)
    bulk_actions = []
    for action, data in chunk:
      bulk_actions.append(action)
      if data is not None:
        bulk_actions.append(data)

    if not bulk_actions:
      return

def bulk(client, actions, stats_only=False, **kwargs):
  success, failed = 0, 0

  # list of errors to be collected is not stats_only
  errors = []

  for ok, item in streaming_bulk(client, actions, **kwargs):
    # go through request-reponse pairs and detect failures
    if not ok:
      if not stats_only:
        errors.append(item)
      failed += 1
    else:
      success += 1

  return success, failed if stats_only else errors

对于索引的批量删除和更新操作,对应的文档格式如下,更新文档中的doc节点是必须的。

{
  '_op_type': 'delete',
  '_index': 'index-name',
  '_type': 'document',
  '_id': 42,
}
{
  '_op_type': 'update',
  '_index': 'index-name',
  '_type': 'document',
  '_id': 42,
  'doc': {'question': 'The life, universe and everything.'}
}

常见错误

  •     SerializationError:JSON数据序列化出错,通常是因为不支持某个节点值的数据类型
  •     RequestError:提交数据格式不正确
  •     ConflictError:索引ID冲突
  •     TransportError:连接无法建立

性能

使用Python操作Elasticsearch数据索引的教程

上面是使用MongoDB和Elasticsearch存储相同数据的对比,虽然服务器和操作方式都不完全相同,但可以看出数据库对批量写入还是比索引服务器更具备优势。

Elasticsearch的索引文件是自动分块,达到千万级数据对写入速度也没有影响。但在达到磁盘空间上限时,Elasticsearch出现了文件合并错误,并且大量丢失数据(共丢了100多万条),停止客户端写入后,服务器也无法自动恢复,必须手动停止。在生产环境中这点比较致命,尤其是使用非Java客户端,似乎无法在客户端获取到服务端的Java异常,这使得程序员必须很小心地处理服务端的返回信息。

Python 相关文章推荐
python实现进程间通信简单实例
Jul 23 Python
解析Python中while true的使用
Oct 13 Python
在python的类中动态添加属性与生成对象
Sep 17 Python
python记录程序运行时间的三种方法
Jul 14 Python
利用django如何解析用户上传的excel文件
Jul 24 Python
python3实现163邮箱SMTP发送邮件
May 22 Python
Python实现数据可视化看如何监控你的爬虫状态【推荐】
Aug 10 Python
python global和nonlocal用法解析
Feb 03 Python
Python连接Hadoop数据中遇到的各种坑(汇总)
Apr 14 Python
Pytorch数据拼接与拆分操作实现图解
Apr 30 Python
Python Pandas模块实现数据的统计分析的方法
Jun 24 Python
Pandas实现批量拆分与合并Excel的示例代码
May 30 Python
用Python实现协同过滤的教程
Apr 08 #Python
在Python中调用ggplot的三种方法
Apr 08 #Python
Python字符串和文件操作常用函数分析
Apr 08 #Python
Python遍历zip文件输出名称时出现乱码问题的解决方法
Apr 08 #Python
python smtplib模块发送SSL/TLS安全邮件实例
Apr 08 #Python
python复制与引用用法分析
Apr 08 #Python
Python导入txt数据到mysql的方法
Apr 08 #Python
You might like
常用星际术语索引(新手指南)
2020/03/04 星际争霸
SONY SRF-22W(33W)的电路分析和维修案例
2021/03/02 无线电
JAVA/JSP学习系列之六
2006/10/09 PHP
动态生成gif格式的图像要注意?
2006/10/09 PHP
新安装的MySQL数据库需要注意的安全知识
2008/07/30 PHP
php cookies中删除的一般赋值方法
2011/05/07 PHP
百度站点地图(百度sitemap)生成方法分享
2014/01/09 PHP
PHP session会话操作技巧小结
2016/09/27 PHP
PHP+JS实现的商品秒杀倒计时用法示例
2016/11/15 PHP
javascript实现焦点滚动图效果 具体方法
2013/06/24 Javascript
js调用css属性写法
2013/09/21 Javascript
修改或扩展jQuery原生方法的代码实例
2015/01/13 Javascript
JS实现的生成随机数的4个函数分享
2015/02/11 Javascript
jQuery实现指定内容滚动同时左侧或其它地方不滚动的方法
2015/08/08 Javascript
jquery ztree实现模糊搜索功能
2016/02/25 Javascript
使用JavaScript实现ajax的实例代码
2016/05/11 Javascript
Javascript中引用类型传递的知识点小结
2017/03/06 Javascript
基于jQuery实现一个marquee无缝滚动的插件
2017/03/09 Javascript
jQuery实现扑克正反面翻牌效果
2017/03/10 Javascript
javaScript 逻辑运算符使用技巧整理
2017/05/03 Javascript
iscroll动态加载数据完美解决方法
2017/07/18 Javascript
JavaScript解析任意形式的json树型结构展示
2017/07/23 Javascript
bootstrap Table服务端处理分页(后台是.net)
2017/10/19 Javascript
webpack4 入门最简单的例子介绍
2018/09/05 Javascript
python自动化脚本安装指定版本python环境详解
2017/09/14 Python
python打包压缩、读取指定目录下的指定类型文件
2018/04/12 Python
Python类中的魔法方法之 __slots__原理解析
2019/08/26 Python
Python @property使用方法解析
2019/09/17 Python
解决Python中回文数和质数的问题
2019/11/24 Python
python操作yaml说明
2020/04/08 Python
详解CSS3媒体查询响应式布局bootstrap 框架原理实战(推荐)
2020/11/16 HTML / CSS
世界上最大的冷却器制造商:Igloo Coolers
2019/07/23 全球购物
七年级历史教学反思
2014/02/05 职场文书
幼儿园教师的考核评语
2014/04/18 职场文书
教师业务培训方案
2014/05/01 职场文书
如何利用 CSS Overview 面板重构优化你的网站
2021/10/24 HTML / CSS