python操作elasticsearch

大小瓶發表於2020-12-07

一、安裝庫

pip install elasticsearch

二、連線庫

from elasticsearch import  Elasticsearch
from datetime import datetime

#都有預設值,可以選擇設定
es = Elasticsearch(
    ['127.0.0.1:9200',"0.0.0.0:9300", "0.0.0.0:9301", "0.0.0.0:9302"], # 連線叢集,以列表的形式存放各節點的IP地址
    sniff_on_start=True,    # 連線前測試
    sniff_on_connection_fail=True,  # 節點無響應時重新整理節點
    sniff_timeout=60,    # 設定超時時間
    # ignore=400,  # 忽略返回的400狀態碼
    # ignore=[400, 405, 502],  # 以列表的形式忽略多個狀態碼
    # http_auth=('elastic', 'changeme')  # 認證資訊
    )

三、叢集資訊

#叢集基本資訊
print(es.info())
#狀態資訊
print(es.cluster.health())

四、插入資料

#索引可以先建立,也可以插入資料時臨時建立
es.indices.create(index='myindex')

#index,doc_type,id都一致時會覆蓋
#插入資料
es.index(index="myindex",doc_type="mytype",id=1,body={"name":"張三","age":18,"time":datetime.now()})
es.index(index="myindex",doc_type="mytype",id=2,body={"name":"李四","age":20,"time":datetime.now()})
es.index(index="myindex",doc_type="mytype",id=4,body={"name1":"李四","name2":"張三","age":20,"time":datetime.now()})
es.index(index="myindex",doc_type="mytype",id=5,body={"name1":"張三","name2":"李四","age":20,"time":datetime.now()})
#沒有索引就建立
es.index(index="testindex",doc_type="mytype",id=3,body={"name":"王五","age":20,"time":datetime.now()})

五、查詢所有資訊

#檢視所有index
print(es.indices.get_alias("*"))
#檢視所有資訊(res['hits']['hits']裡)
res = es.search()
print(res)

六、get查詢資料

res = es.get(index="myindex", doc_type="mytype", id=1)
print(res)
print(res['_source'])

七、search查詢資料

1)查詢所有資料

#查詢所有資料
res = es.search(index="myindex", body={"query":{"match_all":{}}})
print(res)
for hit in res['hits']['hits']:
    print(hit["_source"])

2)term與terms

# term
body = {
    "query": {
        "term": {
            "age": 20
        }
    }
}

# 查詢"age": 20的所有資料
res = es.search(index="myindex", doc_type="mytype", body=body)
print(res)

# terms
body = {
    "query": {
        "terms": {
            "age": [
                18, 20
            ]
        }
    }
}
# 搜尋出"age": 18或"age": 20的所有資料
res = es.search(index="myindex", doc_type="mytype", body=body)
print(res)

3)match與multi_match

# match:匹配name1包含'張'關鍵字的資料
body = {
    "query": {
        "match": {
            "name1": "張"
        }
    }
}
res = es.search(index="myindex", doc_type="mytype", body=body)
print(res)

# multi_match:在name1和name2裡匹配包含深圳關鍵字的資料
body = {
    "query": {
        "multi_match": {
            "query": "四",
            "fields": ["name1","name2"]
        }
    }
}
# # 查詢name1和name2包含"四"關鍵字的資料
res = es.search(index="myindex", doc_type="mytype", body=body)
print(res)

4)ids

body = {
    "query":{
        "ids":{
            # "type":"mytype",
            "values":[
                "1","2"
            ]
        }
    }
}
# 搜尋出id為1或2d的所有資料
res = es.search(index="myindex",doc_type="mytype",body=body)
print(res)

5)複合查詢bool

#bool有3類查詢關係,must(都滿足),should(其中一個滿足),must_not(都不滿足)
body = {
    "query":{
        "bool":{
            "should":[
                {
                    "term":{
                        "name":"張三"
                    }
                },
                {
                    "term":{
                        "age":20
                    }
                }
            ]
        }
    }
}
# 獲取name="張三"或者age=20的所有資料
res = es.search(index="myindex",doc_type="mytype",body=body)
print(res)

6)範圍查詢

'''
range不支援:
    eq 等於  
    neq 不等於
    
range支援:
    gt: greater than 大於
    gte: greater than or equal 大於等於
    lt: less than 小於
    lte: less than or equal 小於等於
'''

body = {
    "query":{
        "range":{
            "age":{
                "gte":18,       # >=18
                "lte":30        # <=30
            }
        }
    }
}
# 查詢18<=age<=30的所有資料
res = es.search(index="myindex",doc_type="mytype",body=body)
print(res)

7)切片查詢

body = {
    "query":{
        "match_all":{}
    },

    "sort": [{"age": {"order": "asc"}}],  # 排序,asc是指定列按升序排列,desc則是指定列按降序排列
    "from":0,    # 從第1條資料開始
    "size":4    # 獲取4條資料
}

res = es.search(index="myindex",doc_type="mytype",body=body)
print(res)

8)字首查詢

body = {
    "query":{
        "prefix":{
            "name":"張"
        }
    }
}
# 查詢字首為"張"的所有資料
res = es.search(index="myindex",doc_type="mytype",body=body)
print(res)

9)萬用字元查詢

body = {
    "query":{
        "wildcard":{
            "name":"*三"
        }
    }
}
# 查詢name以'三'為字尾的所有資料
res = es.search(index="myindex",doc_type="mytype",body=body)
print(res)

10)排序

body = {
    "query":{
        "match_all":{}
    },
    "sort":{
        "age":{                 # 根據age欄位升序排序
            "order":"asc"       # asc升序,desc降序
        }
    }
}
res = es.search(index="myindex",doc_type="mytype",body=body)
print(res)

11)響應過濾

# 只需要獲取_id資料,多個條件用逗號隔開
res = es.search(index="myindex", doc_type="mytype", filter_path=["hits.hits._id"])
print(res)
res = es.search(index="myindex", doc_type="mytype", filter_path=["hits.hits._index,hits.hits._id"])
print(res)

# 獲取所有資料
res = es.search(index="myindex", doc_type="mytype", filter_path=["hits.hits._*"])
print(res)

12)count,匹配數量

# 匹配數量
res = es.count(index="myindex", doc_type="mytype")
print(res)

13)獲取聚合值

'''
min:最小
max:最大
sum:求和
avg:平均值
'''
# 最小值
body = {
    "query":{
        "match_all":{}
    },
    "aggs":{                        # 聚合查詢
        "min_age":{                 # 最小值的key
            "min":{                 # 最小
                "field":"age"       # 查詢"age"的最小值
            }
        }
    }
}

res = es.search(index="myindex", doc_type="mytype",body=body)
print(res)
print(res['aggregations'])

八、更新資料

#更新一條資料,需要指定index,doc_type,id
es.update(index="myindex",doc_type="mytype",id=1,body={"doc":{"age":10}})
#條件更新
'''
其中script的語法為painless,具體語法參考:https://www.elastic.co/guide/en/elasticsearch/reference/6.2/painless-api-reference.html
"script": {
    "source": "def a=ctx._source['ip'].lastIndexOf('.');def sec=ctx._source['ip'].substring(0,a);ctx._source['ipSection']=sec+'.0'"
  }
  
'''
query = {"script": {
                "source": "ctx._source['age']=1"  #改為字串時要加引號,"ctx._source['age']='張三'"
                    },
         'query': {
             'range': {
                 'age': {
                     'lt': 30
                 }
             }
         }
}
res = es.update_by_query(index="myindex",doc_type="mytype",body=query)
print(res)

九、刪除index

es.indices.delete('testindex')
es.delete(index="testindex",doc_type='mytype',id='2')

十、刪除資料

es.delete_by_query(index="myindex", body={'query':{'match':{'any':'data'}}})

相關文章