Python连接ES

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)

对于大表的话建议直接删除索引,再添加新索引。