使用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测试驱动开发实例
Oct 08 Python
零基础写python爬虫之爬虫的定义及URL构成
Nov 04 Python
零基础写python爬虫之urllib2使用指南
Nov 05 Python
python实现用户登陆邮件通知的方法
Jul 09 Python
基于Django filter中用contains和icontains的区别(详解)
Dec 12 Python
python tensorflow学习之识别单张图片的实现的示例
Feb 09 Python
python pandas中DataFrame类型数据操作函数的方法
Apr 08 Python
Python实现点阵字体读取与转换的方法
Jan 29 Python
使用selenium和pyquery爬取京东商品列表过程解析
Aug 15 Python
使用python绘制温度变化雷达图
Oct 18 Python
python 可视化库PyG2Plot的使用
Jan 21 Python
使用Python制作一个数据预处理小工具(多种操作一键完成)
Feb 07 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
PHP对XML内容进行修改和删除实例代码
2016/10/26 PHP
PHP pthreads v3在centos7平台下的安装与配置操作方法
2020/02/21 PHP
use jscript with List Proxy Server Information
2007/06/11 Javascript
JavaScript 拖拉缩放效果
2008/12/10 Javascript
javascript 学习之旅 (1)
2009/02/05 Javascript
JavaScript 应用技巧集合[推荐]
2009/08/30 Javascript
picChange 图片切换特效的函数代码
2010/05/06 Javascript
AeroWindow 基于JQuery的弹出窗口插件
2011/06/27 Javascript
Javascript学习笔记之数组的构造函数
2014/11/23 Javascript
javascript实现平滑无缝滚动
2020/08/09 Javascript
JS定义类的六种方式详解
2016/05/12 Javascript
JavaScript对象数组如何按指定属性和排序方向进行排序
2016/06/15 Javascript
jquery基本选择器匹配多个元素的实现方法
2016/09/05 Javascript
NodeJS使用formidable实现文件上传
2016/10/27 NodeJs
js中小数向上取整数,向下取整数,四舍五入取整数的实现(必看篇)
2017/02/13 Javascript
小程序外卖订单界面的示例代码
2019/12/30 Javascript
Python的Tornado框架异步编程入门实例
2015/04/24 Python
python实现class对象转换成json/字典的方法
2016/03/11 Python
python简单实例训练(21~30)
2017/11/15 Python
Python中单、双下划线的区别总结
2017/12/01 Python
Python OpenCV对本地视频文件进行分帧保存的实例
2019/01/08 Python
用python一行代码得到数组中某个元素的个数方法
2019/01/28 Python
python+mysql实现教务管理系统
2019/02/20 Python
Python找出列表中出现次数最多的元素三种方式
2020/02/24 Python
提高python代码运行效率的一些建议
2020/09/29 Python
Python监听键盘和鼠标事件的示例代码
2020/11/18 Python
PyCharm常用配置和常用插件(小结)
2021/02/06 Python
有关HTML5中背景音乐的自动播放功能
2017/10/16 HTML / CSS
详解使用双缓存解决Canvas clearRect引起的闪屏问题
2019/04/29 HTML / CSS
英国最大的女性服装零售商:Dorothy Perkins
2017/03/30 全球购物
MATCHESFASHION.COM美国官网:英国奢侈品零售商
2018/10/29 全球购物
美国综合购物商城:UnbeatableSale.com
2018/11/28 全球购物
《梅兰芳学艺》教学反思
2014/02/24 职场文书
迎新生欢迎词
2015/01/23 职场文书
spring boot项目application.properties文件存放及使用介绍
2021/06/30 Java/Android
「睡美人」爱洛公主粘土人开订
2022/03/22 日漫