from elasticsearch import Elasticsearch
es = Elasticsearch(hosts=[{"host": "172.17.37.250", "port": 9200}])
body_source = {"bucket": "bigtera", "name": "zhuzhuzhu", "comment": {"id": 3, "price": 25}}
##创建文档
# es.create(index="test1", id="1qert235", body=body_source, doc_type="html")
## index 指定数据的索引 ;id文件的id ; body 文件对应的数据描述信息(_source) ,doc_type 文件类型/注意create数据时id是唯一的 id 的命名一般是文件名md文件名+doc_type
# es.index(index="test1", id="1qert235", body=body_source, doc_type="html", version="1") ## index 创建或修改文件数据 可以设定版本
##更新数据
#1、 es.update(index="test", id="1qert235", body={"doc": body_source}, doc_type="html")
# updateBody = {
# "query": {
# "range": {
# "write_date": {
# "gte": "2019-01-15 12:30:17",
# "lte": "now"
# }
# }
# },
# "script": {
# "inline": "ctx._source.index = params.index",
# "params": {
# "index": 211
# },
# "lang": "painless"
#
# }
# }
#2、es.update_by_query(index="log_index", doc_type='log_index', body=updateBody)
##删除文档
# 删除指定的index、type、id的文档
# res = es.delete(index='test1', doc_type='html', id="1qert235")
# 删除 符合body查询条件的文档 通过body_source的条件搜索
# es.delete_by_query(index="my_index",doc_type="test_type",body=body_source)
deleteBody = {
"query": {
"match":{"bucket":"bucket"}
},
}
res = es.delete_by_query(index="_all",body=deleteBody)
print(res)
##数据切片
##删除index
# es.indices.delete("test1")
#查询
import hashlib
import json
import elasticsearch
import pprint
es = elasticsearch.Elasticsearch([{'host': "172.17.37.250", 'port': 9200}])
body_bool = {"query": {"bool": {"must": [{"wildcard": {"bucket": "big*"}}], "must_not": [], "should": []}}, "from": 0,
"size": 50, "sort": [], "aggs": {}, "version": True}
# es.create(index="bigtera", body={"name": 'big pig', "age": 27},id =10, doc_type="txt")
## must(bool多条件查询: must,should,must_not) 查询的三种方式 must 必须满足 should 应该满足 not_must 不满足, filter过滤
## must 列表 中是联合查询的条件 类型如下:term, perfix, wildcard, regexp, fuzzy, boost, dis_max , [match_all 查询所有的]
##from 设置偏移量, size显示条数 ,sort 排序
##es的aggs可以分为度量聚合和桶聚合,下面就直接实战开发中经常用到的语句
"""
度量聚合:min、max、sum、avg聚合, 度量聚合接收一个输入文档集并生成至少一个统计值sum。
聚合中常用的桶 terms、filter、top_hits
{
"query": { ... },
"size": 0,
"aggs": {
"custom_name1": { //aggs后面接著的是一个自定义的name
"桶": { ... } //再来才是接桶
},
"custom_name2": { //一个aggs裡可以有很多聚合
"桶": { ... }
},
"custom_name3": {
"桶": { ..... },
"aggs": { //aggs可以嵌套在别的aggs裡面
"in_name": { //记得使用aggs需要先自定义一个name
"桶": { ... } //in_name的桶作用的文档是custom_name3的桶的结果
} } } }}
"""
##term 不会对检索串进行分词,将字符作为整体查询
body_term = {"query": {"term": {"name": "python"}}}
# terms, 相当于多个term检索, 类似于SQL中in关键字的用法, 即在某些给定的数据中检索
body_terms = {"query": {"terms": {"name": ["python ,java"]}}}
## prefix query, 就是前缀检索. 比如商品name中有多个以"Java"开头的document, 检索前缀"Java"时就能检索到所有以"Java"开头的文档.
body_perfix = {
"query": {
"prefix": {"name": "java"}
}
}
## wildward query通配符检索, 扫描所有倒排索引, 性能较差.
body_wildward = {
"query": {
"wildcard": {"name": "ja*"}
}
}
## regexp query 正则检索 ,扫描所有倒排索引, 性能较差.
body_regexp = {
"query": {
"regexp": {"name": "jav[a-z]*"}
}
}
## fuzzy query - 纠错检索
# fuzziness的默认值是2 —— 表示最多可以纠错两次.
#
# 说明: fuzziness的值太大, 将削弱检索条件的作用, 也就是说纠错次数太多, 就会导致限定检索结果的检索条件被改变, 失去了限定作用.
body_fuzzy = {
"query": {
"match": {
"name": {
"query": "zhuzhuzhu",
"fuzziness": 2,
"operator": "or"
}
}
},
"sort": [
"comment.price",
]
}
# boost评分权重 - 控制文档的优先级别
#
# 通过boost参数, 令满足某个条件的文档的得分更高, 从而使得其排名更靠前.
body_boost = {
"query": {
"bool": {
"must": [
{"match": {"name": "编程思想"}}
],
"should": [
{
"match": {
"name": {
"query": "艺术",
"boost": 2 # 提升评分权重
}
}
}
]
}
}
}
# 如果我们希望检索结果中 (检索串被分词后的) 关键字匹配越多, 这样的文档就越靠前, 而不是多个子检索中匹配少量分词的文档靠前.
#
# ⇒ 此时可以使用dis_max和tie_breaker
# tie_breaker的值介于0~1之间, Elasticsearch将 bool检索的分数 * tie_breaker的结果与dis_max的最高分进行比较, 除了取dis_max的最高分以外, 还会考虑其他的检索结果的分数.
body_dis_max = {
"query": {
"dis_max": {
"queries": [
{"match": {"name": "虚拟机"}},
{"match": {"desc": "经典"}}
],
"tie_breaker": 0.2 # 对同时满足的文档的分值进行提升
}
}
}
body_dis_max_1 = {
"query": {
"dis_max": {
"queries": [
{
"match": {
"name": {
"query": "虚拟机",
"minimum_should_match": "50%",
"boost": 2
}
}
},
{
"match": {
"desc": {
"query": "经典",
"minimum_should_match": "50%",
"boost": 3
}
}
}
],
"tie_breaker": 0.3
}
}
}
# re = es.search(index="_all", doc_type="object", body=body_fuzzy)
# re = es.search(index="_all", doc_type="", body="")
# doc_type 对应的是 es数据结构中的 "_type"
# re = es.search(index="_all", doc_type="object", body=body_fuzzy)
## params 的使用
# re = es.search(index="_all", params={"request_timeout": 5, "ignore": True}, body=body_fuzzy)
# re = es.search(index="_all", params={"request_timeout": 5, "ignore": True}, body=body_fuzzy)
def str2md5(parmStr):
try:
if isinstance(parmStr, str):
parmStr = parmStr.encode("utf-8")
m = hashlib.md5()
m.update(parmStr)
return m.hexdigest()
except Exception as e:
pass
query_body = {"query": {"bool": {"must": [{"term":{"bucket":"bigtera"}},{"term":{"md5":str2md5("'s3 - 副本 (2).txt'")}}]}}}
# re = es.search(index="",version=True, body={"query": {"term": {"_version": 4}}})
re = es.search(index="",version=True, body=query_body)
"""
{'_id': '10',
'_index': 'bigtera',
'_score': 1.0,
'_source': {'age': 27, 'name': 'big pig'},
'_type': 'txt'}],
"""
pprint.pprint(re)["hits"]["hits"]
实际使用中中文分词普通的分词器查找是不可用的,项目中用的是
query_body.append({"bool": {"should": [{"match_phrase_prefix": {"object_key": "*{}*".format(name)}}]}})
match_phrase_prefix与match_phrase相同,但是它多了一个特性,就是它允许在文本的最后一个词项(term)上的前缀匹配,如果 是一个单词,比如a,它会匹配文档字段所有以a开头的文档,如果是一个短语,比如 "this is ma" ,则它会先进行match_phrase查询,找出 所有包含短语"this is"的的文档,然后在这些匹配的文档中找出所有以"ma"为前缀的文档.
注意:
构造排序,"sort": [{"object_key.keyword":{"order":"asc"}}]