es批量索引
使用Python操作Elasticsearch数据索引的教程
Elasticsearch是一个分布式、Restful的搜索及分析服务器,Apache Solr一样,它也是基于Lucence的索引服务器,但我认为Elasticsearch对比Solr的优点在于:
- 轻量级:安装启动方便,下载文件之后一条命令就可以启动;
- Schema free:可以向服务器提交任意结构的JSON对象,Solr中使用schema.xml指定了索引结构;
- 多索引文件支持:使用不同的index参数就能创建另一个索引文件,Solr中需要另行配置;
- 分布式:Solr Cloud的配置比较复杂。
环境搭建
启动Elasticsearch,访问端口在9200,通过浏览器可以查看到返回的JSON数据,Elasticsearch提交和返回的数据格式都是JSON.
|
1
|
>> bin/elasticsearch -f |
安装官方提供的Python API,在OS X上安装后出现一些Python运行错误,是因为setuptools版本太旧引起的,删除重装后恢复正常。
|
1
|
>> pip install elasticsearch |
索引操作
对于单条索引,可以调用create或index方法。
|
1
2
3
4
5
|
from datetime import datetimefrom elasticsearch import Elasticsearches = 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的文档示例较少,花了不少时间阅读源代码才弄清楚批量索引的提交格式。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
from datetime import datetimefrom elasticsearch import Elasticsearchfrom elasticsearch import helperses = Elasticsearch("10.18.13.3")j = 0count = 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进行测试,会有索引不成功的情况。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
#helpers.py source codedef 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: returndef 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节点是必须的。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
{ '_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:连接无法建立
性能

上面是使用MongoDB和Elasticsearch存储相同数据的对比,虽然服务器和操作方式都不完全相同,但可以看出数据库对批量写入还是比索引服务器更具备优势。
Elasticsearch的索引文件是自动分块,达到千万级数据对写入速度也没有影响。但在达到磁盘空间上限时,Elasticsearch出现了文件合并错误,并且大量丢失数据(共丢了100多万条),停止客户端写入后,服务器也无法自动恢复,必须手动停止。在生产环境中这点比较致命,尤其是使用非Java客户端,似乎无法在客户端获取到服务端的Java异常,这使得程序员必须很小心地处理服务端的返回信息。
es批量索引的更多相关文章
- ES批量索引写入时的ID自动生成算法
对bulk request的处理流程: 1.遍历所有的request,对其做一些加工,主要包括:获取routing(如果mapping里有的话).指定的timestamp(如果没有带timestamp ...
- es修改索引副本个数
es修改索引副本个数 PUT index01/_settings { "number_of_replicas": 2 }
- ES-PHP向ES批量添加文档报No alive nodes found in your cluster
ES-PHP向ES批量添加文档报No alive nodes found in your cluster 2016年12月14日 12:31:40 阅读数:2668 参考文章phpcurl 请求Chu ...
- 批量索引以提高索引速度 -d --data-binary
index create update 第1.2行分别为:信息行.数据行,在索引中增加或更换文档delete 移除文档,只包含信息行 Bulk API | Elasticsearch Referenc ...
- es创建索引的格式,并初始化数据
es创建索引的格式,并初始化数据 学习了:https://www.imooc.com/video/15759 1, 创建格式 POST 127.0.0.1:9200/book/novel/_mappi ...
- ES读写索引内幕分析
一.简介 ES中的索引都进行分片,每个分片都会保存多个副本.这些副本称为复制组,在添加或删除索引时必须同步副本.如果不这样,从不同的副本中读取的索引可能截然不同.保持分片副本同步并从中提供读取的过程被 ...
- es批量导入进一对多的数据
es批量导入进一对多的数据 我有一个产品表 一个产品对应多个属性名 一个属性名对应多个属性值 一个产品还对应一个分类名称 控制层 @ApiOperation(value = "导入所有 ...
- ES 服务器 索引、类型仓库基类 BaseESStorage
/******************************************************* * * 作者:朱皖苏 * 创建日期:20180508 * 说明:此文件只包含一个类,具 ...
- 在ES批量插入数据超时时自动重试
当我们使用ES批量插入数据的时候,一般会这样写代码: from elasticsearch import Elasticsearch,helpers es =Elasticsearch(hosts=[ ...
随机推荐
- 【已转移】【Java架构:基础技术】一篇文章搞掂:Java 8
本文篇幅较长,建议合理利用右上角目录进行查看(如果没有目录请刷新). 一.Java的历史与演变 目的:为完全了解Java,需要理解Java的诞生原因.成型动力以及他继承的思想. 计算机语言的创新与发展 ...
- 团队冲刺DAY3
DESUtil.java是包含加密解密抽象类的Java文件 DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准 ...
- 20175203 2018-2019-2《Java程序设计》第四周学习总结
## 教材学习内容总结 第五章内容知识点总结: 子类父类的定义格式: class 子类名 extends 父类名 { } 定义子类时用extends Object类是所有类的祖先类,即最原始类. 子类 ...
- tomcat7以下线程控制
web server允许的最大线程连接数还受制于操作系统的内核参数设置,通常Windows是2000个左右,Linux是1000个左右. 1.编辑tomcat安装目录下的conf目录下的server. ...
- 53、tensorflow基本操作
import tensorflow as tf import numpy as np x_data = np.float32(np.random.rand(2,100)) print(x_data) ...
- oracle使用execute immediate方式完成函数动态传入表名并操作 返回新的主键id值
CREATE OR REPLACE FUNCTION SEQ1 (v_bname in VARCHAR2) return NUMBER is v_bcount NUMBER; BEGIN execut ...
- 人工智能-动物识别专家系统算法Python + Pyqt 实现
一.基础知识库 有毛发 哺乳动物 - 有奶 哺乳动物 - 有羽毛 鸟 - 会飞 会下蛋 鸟 - 吃肉 食肉动物 - 有犬齿 有爪 眼盯前方 食肉动物 - 哺乳动物 有蹄 有蹄类动物 - 哺乳动物 反刍 ...
- python学习笔记:数据类型——数字、字符串、元祖、字典
计算机顾名思义就是可以做数学计算的机器,因此,计算机程序理所当然地可以处理各种数值.但是,计算机能处理的远不止数值,还可以处理文本.图形.音频.视频.网页等各种各样的数据,不同的数据,需要定义不同的数 ...
- linux nohup python 后台运行无输出问题
参考:https://blog.csdn.net/zj360202/article/details/78894512 nohup python test.py & nohup python t ...
- SQL Server 2014 中新建登录及权限分配【界面版】
本篇经验将和大家介绍分配SQL Server 2014 中,新建登录用户,分配权限,并指定该用户的数据库的方法,希望对大家的工作和学习有所帮助! 方法/步骤 1 打开 MS SQL Server Ma ...