用python操作elasticsearch,你会吗?
作者:互联网
一、基本查询
from elasticsearch import Elasticsearch
# 建立连接
es = Elasticsearch(
hosts={'192.168.0.120', '192.168.0.153'}, # 地址
timeout=3600 # 超时时间
)
es.search(index='pv23') # index:选择数据库
此方法是默认查询,由于没有任何筛选条件,会默认显示前10条数据的所有信息
二、filter_path
添加过滤路径。通过指定字段,只显示数据的指定字段信息(默认显示所有字段的信息)。
from elasticsearch import Elasticsearch
# 建立连接
es = Elasticsearch(
hosts={'192.168.0.120', '192.168.0.153'}, # 地址
timeout=3600 # 超时时间
)
# 定义过滤字段,最终只显示此此段信息
filter_path=['hits.hits._source.ziduan1', # 字段1
'hits.hits._source.ziduan2'] # 字段2
es.search(index='pv71', filter_path=filter_path) # 指定字段:filter_path
三、条件查询
通过制定body,进行条件查询。类似于mysql中的where。
1、切片查询
from elasticsearch import Elasticsearch
# 建立连接
es = Elasticsearch(
hosts={'192.168.0.120', '192.168.0.153'}, # 地址
timeout=3600 # 超时时间
)
# body指定查询条件
body = {
'from': 0, # 从0开始
'size': 20
# 取20个数据。类似mysql中的limit 0, 20。 注:size可以在es.search中指定,也可以在此指定,默认是10
}
# 定义过滤字段,最终只显示此此段信息
filter_path=['hits.hits._source.ziduan1', # 字段1
'hits.hits._source.ziduan2'] # 字段2
es.search(index='pv23', filter_path=filter_path, body=body) # 指定查询条件
2、match,模糊查询
body = {
'query': { # 查询命令
'match': { # 查询方法:模糊查询(会被分词)。比如此代码,会查到只包含:“我爱你”, “中国”的内容
'ziduan1': '我爱你中国'
}
},
'size': 20 # 不指定默认是10,最大值不超过10000(可以修改,但是同时会增加数据库压力)
}
# size的另一种指定方法
es.search(index='pv23', filter_path=filter_path, body=body, size=200) # 指定size,默认是10
3、match_phrase,模糊查询
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群991032883
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
body = {
'query': { # 查询命令
'match_phrase': { # 查询方法:模糊查询(不会被分词)。会查到包含:“我爱你中国”的内容
'ziduan1': '我爱你中国'
}
}
}
注:内容中的下划线,等标点符号会被忽略,有与没有的效果一样
4、term,精准单值查询
注:此方法只能查询一个字段,且只能指定一个值。类似于mysql中的where
ziduan=‘a’
body ={
'query':{
'term':{
'ziduan1.keyword': '我爱你中国' # 查询内容等于“我爱你中国的”的数据。查询中文,在字段后面需要加上.keyword
# 'ziduan2': 'I love China'
}
}
}
5、terms,精准多值查询
#此方法只能查询一个字段,但可以同时指定多个值。类似于mysql中的where ziduan in (a, b,c...)
body ={
"query":{
"terms":{
"ziduan1": ["我爱你中国", "I love China"] # 查询ziduan1=a或=b...的数据
}
}
}
6、multi_match,多字段查询
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群991032883
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
# 查询多个字段中都包含指定内容的数据
body = {
"query":{
"multi_match":{
"query":"我爱你中国", # 指定查询内容,注意:会被分词
"fields":["ziduan1", "ziduan2"] # 指定字段
}
}
}
7、prefix,前缀查询
body = {
'query': {
'prefix': {
'ziduan.keyword': '我爱你' # 查询前缀是指定字符串的数据
}
}
}
# 注:英文不需要加keyword
8、wildcard,通配符查询
body = {
'query': {
'wildcard': {
'ziduan1.keyword': '?爱你中*' # ?代表一个字符,*代表0个或多个字符
}
}
}
# 注:此方法只能查询单一格式的(都是英文字符串,或者都是汉语字符串)。两者混合不能查询出来。
9、regexp,正则查询
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群991032883
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
body = {
'query': {
'regexp': {
'ziduan1': 'W[0-9].+' # 使用正则表达式查询
}
}
}
10、bool,多条件查询
# must:[] 各条件之间是and的关系
body = {
"query":{
"bool":{
'must': [{"term":{'ziduan1.keyword': '我爱你中国'}},
{'terms': {'ziduan2': ['I love', 'China']}}]
}
}
}
# should: [] 各条件之间是or的关系
body = {
"query":{
"bool":{
'should': [{"term":{'ziduan1.keyword': '我爱你中国'}},
{'terms': {'ziduan2': ['I love', 'China']}}]
}
}
}
# must_not:[]各条件都不满足
body = {
"query":{
"bool":{
'must_not': [{"term":{'ziduan1.keyword': '我爱你中国'}},
{'terms': {'ziduan2': ['I love', 'China']}}]
}
}
}
# bool嵌套bool
# ziduan1、ziduan2条件必须满足的前提下,ziduan3、ziduan4满足一个即可
body = {
"query":{
"bool":{
"must":[{"term":{"ziduan1":"China"}}, # 多个条件并列 ,注意:must后面是[{}, {}],[]里面的每个条件外面有个{}
{"term":{"ziduan2.keyword": '我爱你中国'}},
{'bool': {
'should': [
{'term': {'ziduan3': 'Love'}},
{'term': {'ziduan4': 'Like'}}
]
}}
]
}
}
}
11、exists,存在字段查询
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群991032883
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
body = {
'query': {
'exists': {'field': 'ziduan1'} # 查询存在ziduan1的数据
}
}
# exists、bool嵌套查询
# 存在ziduan1的情况下,ziduan2的值必须为指定字段
body = {
"query":{
"bool":{
"must":[{'exists': {'field': 'ziduan1'}},
{"term":{"ziduan2.keyword": '我爱你中国'}},
]
}
}
}
12、大于小于查询
body = {
"query": {
"range": {
"ziduan1":{
"gte": 3, # 大于
"lt": 20 # 小于
}
}
}
}
13、nest,json数据查询
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群991032883
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
body = {
'query': {
'nested': {
'path': 'ziduan1', # 指定json数据的字段
'query': { # 指定查询方式
'term': {'ziduan1.ziduan2': '我爱你中国'} # 根据ziduan1里面的ziduan2数据查询
}
}
}
}
# nest、bool嵌套查询
body = {
'query': {
'bool': {
'must': [
{'term':{"ziduan3" : "I love China"}},
{'nested': { # json查询
'path': 'ziduan1',
'query': { # 指定查询方式
'term': {'ziduan1.ziduan2': '我爱你中国'} # 根据ziduan1里面的ziduan2数据查询
}
}}
]
}
}
}
14、排序
body = {
"query":{ # 指定条件,可以使用以上的任何条件等查询数据。然后再对符合条件的数据进行排序
"match_all":{}
},
"sort":{ # 对满足条件的数据排序
"age":{ # 根据age字段排序
"order":"asc" # asc升序,desc降序
}
}
}
# 多字段排序,注意顺序!写在前面的优先排序
body = {
"query":{
"match_all":{}
},
"sort":[{
"age":{
"order":"asc" # 先根据age升序
}},
{"name":{ # 后根据name字段升序排序
"order":"asc" # asc升序,desc降序
}}],
}
15、scroll,翻页查询(数据量小可以使用此方法,数据量大推荐使用search_after方法–见下一个方法)
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群991032883
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
body={
'query':{'match_all': {}},
'sort': {'zidan6': 'asc'}, # 翻页需要先使用sort排序,与search_after类似
}
# size:设置一页数据量
result = es.search(index='pv91', scroll='1m', size=5, body=body)
# 获取总的数据量,用于得到总的数据页数
total = result['hits']['total']
# 获取初始翻页id
scrid = result['_scroll_id']
# 第一页的数据
result = es.search(index='patent_cn_v71',size=5, body=body, filter_path=['hits.hits._source.ziduan1', 'hits.hits._source.ziduan2.ziduan2_1'])
# 开始翻页
for i in range(5): #翻5页
print(result, '\n')
print('*' * 50, '第{}页'.format(i), '*' * 50)
result = es.scroll(scroll_id=scrid, scroll='1m', filter_path=['hits.hits._source.ziduan1', 'hits.hits._source.ziduan2.ziduan2_1'])
16、search_after,翻页查找(推荐此方法)
content_size = 3000 # 设置一页的数据量
size_cont = content_size
next_id = 0 # 初始化next_id,每次循环是从 此数据 之后的第1个数据开始
while size_cont == content_size:
body = {
"query": {
"range": {
"update_time":{
"gte": "2019-10-14"
}
}
},
'sort': {'ziduan2': 'asc'}, # 以ziduan2为next_id,需要先对其进行排序
'search_after': [next_id], # 从此数据之后的第1个数据开始,但不包含此数据
'size': content_size # 指定当前页数据量
}
filter_path = [
'hits.hits._source.ziduan1',
'hits.hits._source.ziduan2'
]
rt = es.search(index='pv1', body=body, filter_path=filter_path)['hits']['hits']
size_cont = len(rt) # 更新循环条件:若数据量不等于指定的数据量,说明遍历到最后的一页数据了
for result in rt:
try:
app_date = result['_source']['ziduan1']
except:
continue
try:
ziduan2 = result['_source']['ziduan2']
next_id = ziduan2 # 更新next_id
except:
app_text = ''
17、聚合查询
# 统计符合条件的指定字段的数据中,各数据的个数
'''
body = {
# 'query': {
# 'match_all': {}
# },
'size': 0, # 设置0为条件查询后的数据显示条数,默认显示10条
'aggs':{
'num_ipcr': { # 自定义buckets
'terms': {
'field': 'ziduan1', # 需要查找的字段
'size': 10, # 设置聚合数据显示条数
}
}
},
}
# 嵌套聚合:根据聚合后的数据大小再进行聚合
body = {
'size': 0, # 设置0为条件查询后的数据显示条数,默认显示10条
"aggs": {
"agroup": {
"nested": {"path": "ziduan1"}, # 选择ziduan1里面的数据量再进行聚合
"aggs": {
"de_inventor": {
"terms": {"field": "ziduan1.ziduan1_1.keyword", "size": 200000}
}
},
},
},
}
# 去重统计
body = {
'size': 0,
'aggs': {
'discount_ipcr': {
'cardinality':{ # 去重统计
'field': 'ziduan1',
'precision_threshold': 100 # 保证100个以内准确率接近100%,每个类别会占用100字节的内存
},
},
}
}
# 结果返回值说明
"""
doc_count_error_upper_bound: 表示没有在这次聚合中返回、但是可能存在的潜在聚合结果
sum_other_doc_count:表示这次聚合中没有统计到的文档数
buckets:聚合结果,默认由高到低排列。key表示聚合元素的值,doc_count表示元素出现的次数。注意,这里的doc_count也是不准确的
"""
四、建立es数据
es.indices.create(index='my-index', ignore=400) # 建立索引(理解为数据库,就是es.search(index='')查找时候用到的index)
es.index(index="my-index", id=0, body={'name': 'jaychou', "age": 30, "sex": 'male'}) # 插入数据:
标签:body,hits,python,查询,ziduan2,ziduan1,elasticsearch,query,操作 来源: https://blog.csdn.net/sehun_sx/article/details/123585584