python 连接ES操作
1.准备事项
1.1 安装elasticsearch,这里以安装7.9.1版本为例
pip3 install elasticsearch==7.9.1
2.连接ES
安装好elasticsearch扩展后就可以使用python进行连接es操作了
from elasticsearch import Elasticsearch
es = Elasticsearch("http://192.168.1.1:9200",http_auth=('username', 'password'), timeout=20)
如果有多个es,可以存放多个ip
es = Elasticsearch("['http://192.168.1.1:9200','http://192.168.1.2:9200']",http_auth=('username', 'password'), timeout=20)
3.创建索引
链接上es后就可以创建索引了
使用命令
result = es.indices.create(index='user_info',ignore=400)
print(result)
创建成功的话会返回
{'acknowledged': True, 'shards_acknowledged': True, 'index': 'user_info'}
4.插入数据
创建好索引后,我们就可以往表里面插入数据,如果是mysql表的数往es存放,本身有自增id的话,可以这么创建
data={'id':1,'name':'zhangsan','sex':'男','age':30,'hobby':'basketball,football','add_time':'2023-01-01 10:00:00'}
result = es.create(index='user_info',id=data['id'],body=data)
print(result)
插入成功后会返回下面的数据
{'_index': 'user_info', '_type': '_doc', '_id': '1', '_version': 1, 'result': 'created', '_shards': {'total': 2, 'successful': 2, 'failed': 0}, '_seq_no': 12, '_primary_term': 1}
这里我们可以看到生成的_id字段值和id是一样的
下面我再循环插入一些数据
dataList = [
{'id':2,'name':'lisi','sex':'男','age':20,'hobby':'football','add_time':'2023-01-11 10:00:00'},
{'id':3,'name':'wanger','sex':'男','age':40,'hobby':'swim,football','add_time':'2023-02-01 10:00:00'},
{'id':4,'name':'hanmei','sex':'女','age':18,'hobby':'run,football','add_time':'2023-02-03 10:00:00'},
{'id':5,'name':'lily','sex':'女','age':25,'hobby':'badminton','add_time':'2023-02-10 10:00:00'}
]
for d in dataList:
es.create(index='user_info', id=d['id'], body=d)
如果表字段没有自增id的话,可以使用这种方式插入数据
data = {'name':'liudehua','sex':'男','age':30,'hobby':'sing,acting','add_time':'2023-01-01 10:00:00'}
result = es.index(index="user_info", body=data)
print(result)
返回结果如下,这个时候生成的_id是es自动帮你生成的,因为你没有传id值给它
{'_index': 'user_info', '_type': '_doc', '_id': 'U8EtgoYB3nwluujTOwxY', '_version': 1, 'result': 'created', '_shards': {'total': 2, 'successful': 2, 'failed': 0}, '_seq_no': 17, '_primary_term': 1}
5.查询数据
插入数据候我们就可以进行查询,下面看几个常用的例子
5.1根据主键id查找
result = es.get(index='user_info', id=2)
print(result)
返回结果
{'_index': 'user_info', '_type': '_doc', '_id': '2', '_version': 1, '_seq_no': 13, '_primary_term': 1, 'found': True, '_source': {'id': 2, 'name': 'lisi', 'sex': '男', 'age': 20, 'hobby': 'football', 'add_time': '2023-01-11 10:00:00'}}
5.2 根据字段值进行精确查找
body = {
"query":{
"term":{
"name":"liudehua"
}
}
}
result = es.search(index='user_info',body=body)
结果返回
{'took': 0, 'timed_out': False, '_shards': {'total': 1, 'successful': 1, 'skipped': 0, 'failed': 0}, 'hits': {'total': {'value': 1, 'relation': 'eq'}, 'max_score': 1.540445, 'hits': [{'_index': 'user_info', '_type': '_doc', '_id': 'U8EtgoYB3nwluujTOwxY', '_score': 1.540445, '_source': {'name': 'liudehua', 'sex': '男', 'age': 30, 'hobby': 'sing,acting', 'add_time': '2023-01-01 10:00:00'}}]}}
5.3 根据字段值模糊匹配
#查找兴趣爱好喜欢足球的
body = {
"query":{
"match":{
"hobby":"football"
}
}
}
result = es.search(index='user_info',body=body)
返回4条记录,结果如下
{'took': 1, 'timed_out': False, '_shards': {'total': 1, 'successful': 1, 'skipped': 0, 'failed': 0}, 'hits': {'total': {'value': 4, 'relation': 'eq'}, 'max_score': 0.52827823, 'hits': [{'_index': 'user_info', '_type': '_doc', '_id': '2', '_score': 0.52827823, '_source': {'id': 2, 'name': 'lisi', 'sex': '男', 'age': 20, 'hobby': 'football', 'add_time': '2023-01-11 10:00:00'}}, {'_index': 'user_info', '_type': '_doc', '_id': '1', '_score': 0.4084168, '_source': {'id': 1, 'name': 'zhangsan', 'sex': '男', 'age': 30, 'hobby': 'basketball,football', 'add_time': '2023-01-01 10:00:00'}}, {'_index': 'user_info', '_type': '_doc', '_id': '3', '_score': 0.4084168, '_source': {'id': 3, 'name': 'wanger', 'sex': '男', 'age': 40, 'hobby': 'swim,football', 'add_time': '2023-02-01 10:00:00'}}, {'_index': 'user_info', '_type': '_doc', '_id': '4', '_score': 0.4084168, '_source': {'id': 4, 'name': 'hanmei', 'sex': '女', 'age': 18, 'hobby': 'run,football', 'add_time': '2023-02-03 10:00:00'}}]}}
5.4 查找某条记录存不存在
在某些场景我们需要查询某条记录存不存在,可以直接使用exist方法,返回True和False
exist = es.exists(index="user_info",id=2)
print(exist)
True
5.5 自定义sql查询
对于一些场景,想自己写sql也是可以的
body={
'query':'select * from user_info where age>25 '
}
result = es.sql.query(body=body)
print(result)
结果返回如下
{'columns': [{'name': 'add_time', 'type': 'text'}, {'name': 'age', 'type': 'long'}, {'name': 'hobby', 'type': 'text'}, {'name': 'id', 'type': 'long'}, {'name': 'name', 'type': 'text'}, {'name': 'sex', 'type': 'text'}], 'rows': [['2023-01-01 10:00:00', 30, 'basketball,football', 1, 'zhangsan', '男'], ['2023-02-01 10:00:00', 40, 'swim,football', 3, 'wanger', '男'], ['2023-01-01 10:00:00', 30, 'sing,acting', None, 'liudehua', '男']]}
es里面还有其他更复杂的查询场景,如果想更深入的了解的话可以参考下官网文档 https://elasticsearch-py.readthedocs.io/en/7.9.1/
6.修改数据
es也是可以修改数据的
#修改id为1的用户的兴趣爱好
body={
"doc":{
"hobby":"swim,game"
}
}
es.update(index='user_info',id=1,body=body)
再次查询用户id=1用户数据如下,已经变成了swim,game
{'_index': 'user_info', '_type': '_doc', '_id': '1', '_version': 2, '_seq_no': 18, '_primary_term': 1, 'found': True, '_source': {'id': 1, 'name': 'zhangsan', 'sex': '男', 'age': 30, 'hobby': 'swim,game', 'add_time': '2023-01-01 10:00:00'}}
7.删除数据
7.1 根据主键id删除
如果我们知道数据的主键id是多少,这是可以根据主键id进行删除数据
result = es.delete(index='user_info',id=1)
print(result)
删除成功返回如下结果
{'_index': 'user_info', '_type': '_doc', '_id': '1', '_version': 3, 'result': 'deleted', '_shards': {'total': 2, 'successful': 2, 'failed': 0}, '_seq_no': 19, '_primary_term': 1}
再次查询id=1用户数据发现查不到
body = {
"query":{
"term":{
"id":"1"
}
}
}
result = es.search(index='user_info',body=body)
{'took': 126, 'timed_out': False, '_shards': {'total': 1, 'successful': 1, 'skipped': 0, 'failed': 0}, 'hits': {'total': {'value': 0, 'relation': 'eq'}, 'max_score': None, 'hits': []}}
7.2 根据查询条件进行删除
body={
"query": {
"match": {
"name":"liudehua"
}
}
}
result = es.delete_by_query(index='user_info',body=body)
print(result)
删除成功返回信息如下
{'took': 3218, 'timed_out': False, 'total': 1, 'deleted': 1, 'batches': 1, 'version_conflicts': 0, 'noops': 0, 'retries': {'bulk': 0, 'search': 0}, 'throttled_millis': 0, 'requests_per_second': -1.0, 'throttled_until_millis': 0, 'failures': []}
7.3 清空某个表的所有数据
对于一些小表,想清除某个表的所有数据可以使用下面的方式
body={
"query": {
"match_all": {}
}
}
es.delete_by_query(index='user_info',body=body)
对于大表的话建议直接删除索引,再添加新索引。