python 中的elasticsearch的使用



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"}}]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值