Python 操作Elasticsearch之elasticsearch模块
官方文档:https://elasticsearch-py.readthedocs.io/en/master/
mac下的操作
01 基础
01-01 Elasticsearch 基本操作
- 启动 elasticsearch
brew services start elasticsearch
# 或者
elasticsearch
- 停止elasticsearch
brew services stop elasticsearch
或者
control + c
后台浏览
http://localhost:9200
01-02 在python中引入
安装Elasticsearch模块
pip3 install elasticsearch
简单基本操作
- 增
from elasticsearch import Elasticsearch
ES = ["127.0.0.1:9200", ]
es = Elasticsearch(
ES,
# 启动前嗅探es集群服务器
sniff_on_start=True,
# es集群服务器结点连接异常时是否刷新es节点信息
sniff_on_connection_fail=True,
# 每60秒刷新节点信息
sniffer_timeout=60
)
# 必须指定id,索引相同的id不能重复,id可以是数字字符串
es.craete(index="索引", id=1, doc_type="类型", body={})
# 不用指定id,是随机的
es.index(index="索引", doc_type="dict", body={})
- 删
es.delete(id="id", index="索引", doc_type="类型")
# 注意三个值必填,精准删除,没有时会报错
"""
参数
index 索引
id 数据id
doc_type 数据类型
"""
# 可以指定body搜索指定数据删除
es.delete_by_query(index='books', body=body)
- 查询
es.search() # 查询所有的
"""
index
doc_type
body
"""
# get
es.get(index="books", doc_type="dict", id=2)
"""
参数
index 索引 必填
doc_type 数据类型 必填
id 必填
"""
注意:
get三个参数必填,如果没找到会报错
02 操作
02-01 写入
操作模版
from elasticsearch_dsl import connections
from elasticsearch.client import IndicesClient
type_dict = {
"text": {"type": "text"},
"keyword": {"type": "keyword"},
"ip": {"type": "ip"},
"long": {"type": "long"},
"double": {"type": "double"},
"boolean": {"type": "boolean"},
"integer": {"type": "integer"}
}
mappings = {
"web_log": {
"_source": {
"enabled": True
},
"properties": {
"remote_addr": type_dict["ip"],
"time_local": {
"type": "date",
"format": "dd/MMM/yyyy:HH:mm:ss Z"
},
"body_bytes_sent": type_dict["long"],
"request_length": type_dict["long"],
"bytes_sent": type_dict["long"],
"request_time": type_dict["double"],
"idss_action": type_dict["integer"],
}
}
}
template = {
"index_patterns": ["web_bubble_index*"],
"settings": {
"index": {
"refresh_interval": "30s",
"number_of_shards": "12",
"number_of_replicas": "2"
},
"translog": {
"sync_interval": "30s",
"durability": "async",
"flush_threshold_size": "1000mb"
}
},
"mappings": mappings
}
es = connections.create_connection(hosts="127.0.0.1:9200", timeout=60, http_compress=True,
sniff_on_connection_fail=True, )
# 设置模版
IndicesClient(es).put_mapping("模版名字", "模版")
# 获取模版
IndicesClient(es).get_template(name="模版名字")
# 删除名字
IndicesClient(es).delete_template(name="模版名字")
写入es库
- 普通写入
es.index(index="索引", doc_type="dict", body={})
- 批量写入
from elasticsearch.helpers import bulk
bulk(es, [body,])
02-02 查询
普通查询
- match_all
查看所有文档,相当于不做筛选条件
body = {
"query": {
"match_all": {}
}
}
es.search(index="books", body=body)
- size from
size显示几条,from从第几条开始,默认第一条
显示前几条
# 第一种
body = {
"query": {
"match_all": {
}
},
}
es.search(index="books", body=body, size=2)
# 第二种
body = {
"query": {
"match_all": {
}
},
"size": 2
}
es.search(index="books", body=body)
# 显示前两条,search中的参数优先级高
从第一条开始显示几条
# 第一种
body = {
"query": {
"match_all": {
}
},
"from": 5
}
es.search(index="books", body=body, size=2)
# 第二种
body = {
"query": {
"match_all": {
}
},
"from": 5,
"size": 2
}
es.search(index="books", body=body)
# 从第五条开始显示前两条
注意:
size、from和query同级,都可以用
- term
term query会去倒排索引中寻找确切的term,它并不知道分词器的存在,这种查询适合keyword、numeric、date等明确值的
查询某个字段的某个关键字
body = {
"query":{
"term":{
"name": "java"
}
}
}
es.search(index="books", body=body)
# name是java的数据的前两条,size限制显示数量
精确匹配,注意query中的格式,value表示一个匹配的数据,注意只支持一个key
- terms
查询某个字段里含有多个关键词的文档
body = {
"query":{
"terms":{
"name": ["java", "python"]
}
}
}
es.search(index="books", body=body)
# name是python或者java
注意:
只支持一个key,value必须是了列表或者元组
- match
match query 知道分词器的存在,会对field进行分词操作,然后再查询
body = {
"query":{
"match":{
"name": "java python"
}
}
}
es.search(index="books", body=body)
# name是java或者是python的数据
注意:
key只能有一个,value可以是字符串或者数字
一般情况是字符串,可以以各种类型去分割,空格,逗号,|等等都可以识别
- multi_match
可以指定多个key
body = {
"query": {
"multi_match": {
"query": "python java",
"fields": ["name", "book_name"]
}
}
}
es.search(index="books", body=body)
# name或者book_name字段值是python或者是java的数据
注意:
query指定的是要筛选的value值,必须是字符串或者数字,可以是多个,分词
fields是指定的key值,必须是列表或者是元组
只要fields中的key中有query指定的value,都被筛选
复合查询
- bool
有三类查询关系
must 都满足
should 只要满足一个
must_not 都不满足
基本语法
可以一块用
body = {
"query": {
"bool": {
"should": [
{
"term": {
"name": "java"
}
},
{
"terms": {
"name": ["java", "python"]
}
},
{
"match": {
"name": "java python"
}
},
{
"multi_match": {
"query": "python java",
"fields": ["name", "book_name"]
}
}
],
"must": [],
"must_not": []
}
}
}
es.search(index="books", body=body)
注意:
每个查询类中都能写多个查询方法
- range
范围查询
body = {
"query": {
"range": {
"price": {
"lt": 180,
"gte": 10
}
}
}
}
es.search(index="books", body=body)
"""
price 大于等于10小于180
lt 小于
gt 大于
lte 小于等于
"""
注意:
可以只写一个,例如大于10
- prefix
前缀—以什么开头
body = {
"query":
{
"prefix": {
"name": "j"
}
}
}
es.search(index="books", body=body)
# name以j开头的数据
- wildcard
通配符—正则表达式
body = {
"query": {
"wildcard": {
"name": "*v*"
}
}
}
es.search(index="books", body=body)
"""
name中包含v的所有数据,
*a 以a结尾
a* 以a开头
"""
排序
- sort
desc降序
asc升序
body = {
"query": {
"term": {
"name": "java"
}
},
"sort": {
"age": {
"order": "desc"
}
}
}
es.search(index="books", body=body, size=2)
# name是java的数据,按年龄是降序,显示前两条
注意:
sort和query同级
其他
- exists
是否存在数据,结果是布尔值
es.exists(index="books", doc_type="dict", id=1)
"""
参数
index 索引必填
doc_type 数据类型 必填
id 必填
"""
- get_source
直接返回body数据
es.get_source(id=2, index="books", doc_type="dict")
注意:
id、index、doc_type必填,没数据会报错
- ids
筛选id
body = {
"query": {
"ids": {
"type": "dict",
"values": [1, 2]
}
}
}
es.search(index="books", body=body)
# 意思是id是1或者2的数据
- filter_path
筛选显示数据的字段
body = {
"query": {
"term": {
"name": "java"
}
},
"sort": {
"age": {
"order": "desc"
}
}
}
es.search(index="books", body=body, filter_path=["hits.hits._id", "hits.hits._source.name"])
# 支持*,匹配任何字段或者字段的一部分
es.search(index="books", body=body, filter_path=["hits.hits._*",])
"""
显示是数据的_id,和数据的name
可以限制显示多个字段,以逗号隔开
没有该字段时,不显示
"""
- count
数据数量
body = {
"query": {
"term": {
"name": "java"
}
}
}
result = es.count(index="books", body=body)
# 结果是字典result.get("count")
- match_phrase
和term一样,不切分
body = {
"query": {
"match_phrase": {
"name": "java python"
}
}
}
es.search(index="books", body=body)
# name的值是java python的数据
查询总结
代码加解释
from elasticsearch import Elasticsearch
es = Elasticsearch()
body = {
"query": {
"bool": {
"should": [
{
"term": {
"name": "python"
}
},
{
"terms": {
"name": ["java", ]
}
},
{
"match": {
"author": "lynn"
}
},
{
"multi_match": {
"query": "lynn 田少",
"fields": ["publish", "author"]
}
},
{
"prefix": {
"name": "金"
}
},
{
"ids": {
"type": "dict",
"values": [1, 2]
}
}
],
"must":[
{
"range": {
"price": {
"lt": 200,
}
}
},
{
"wildcard": {
"name": "*梅*"
}
}
],
"must_not": [
{
"range": {
"price": {
"lt": 0
}
}
}
]
}
},
"sort": {
"price": {
"order": "desc"
}
},
"from": 2,
"size": 3
}
es.search(index="books", body=body, filter_path=["hits.hits._source.name", "hits.hits._id"])
注意:
方法都可以放在bool中