elasticsearch & python 入门

官方文档:官方文档
API文档:API文档
参考:Elasticsearch的介绍 以及使用python操作es详细步骤

和DB对应关系

Relational DB -> Databases -> Tables -> Rows -> Columns
Elasticsearch -> Indices   -> Types  -> Documents -> Fields

安装:以7.14.0版本为例

# 安装es
curl -L -O https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.14.0-linux-x86_64.tar.gz
tar -xzvf elasticsearch-7.14.0-linux-x86_64.tar.gz
cd elasticsearch-7.14.0
./bin/elasticsearch  # 启动es

# 安装中文分词插件,安装后需要重新启动es。
# 相关git:https://github.com/medcl/elasticsearch-analysis-ik/releases
./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.14.0/elasticsearch-analysis-ik-7.14.0.zip

基础python函数

使用前先pip install elasticsearch

创建index:es.indices.create

from elasticsearch import Elasticsearch

index_name = '20210801'
# 创建index
es = Elasticsearch()
result = es.indices.create(index=index_name, ignore=400) # ignore放置忽略错误的类型
print(result) # acknowledged 为True表示创建成功

删除index:es.indices.delete

result = es.indices.delete(index=index_name, ignore=[400, 404])
print(result)

更新数据:es.update

需要用到id

data = {
    'title': '美国留给伊拉克的是个烂摊子吗',
    'url': 'http://view.news.qq.com/zt2011/usa_iraq/index.htm',
    'date': '2011-12-16'
}

# update方法
result = es.update(index=index_name, doc_type='politics', body=data, id=1)
print(result)

# index方法
es.index(index=index_name, doc_type='politics', body=data, id=1)

删除数据:es.delete

# 删除一条数据
result = es.delete(index=index_name, doc_type='politics', id=1) 
# 删除所有的数据
es.delete_by_query('log_level', body={"query": {"match_all": {}}}) 

查询数据:es.search & es.get

  • es.get:按照id查询
    es.get(index='indexName', doc_type='typeName', id='idValue')
    
  • es.search
    # 1.新建一个索引并指定需要分词的字段
    from elasticsearch import Elasticsearch
     
    es = Elasticsearch()
    mapping = {
        'properties': {
            'title': {
                'type': 'text',
                'analyzer': 'ik_max_word',
                'search_analyzer': 'ik_max_word'
            }
        }
    }
    es.indices.delete(index=index_name, ignore=[400, 404])
    es.indices.create(index=index_name, ignore=400)
    result = es.indices.put_mapping(index=index_name, doc_type='politics', body=mapping)
    print(result)
    
    # 2.插入几条新的数据
    datas = [
        {
            'title': '美国留给伊拉克的是个烂摊子吗',
            'url': 'http://view.news.qq.com/zt2011/usa_iraq/index.htm',
            'date': '2011-12-16'
        },
        {
            'title': '公安部:各地校车将享最高路权',
            'url': 'http://www.chinanews.com/gn/2011/12-16/3536077.shtml',
            'date': '2011-12-16'
        },
        {
            'title': '中韩渔警冲突调查:韩警平均每天扣1艘中国渔船',
            'url': 'https://news.qq.com/a/20111216/001044.htm',
            'date': '2011-12-17'
        },
        {
            'title': '中国驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首',
            'url': 'http://news.ifeng.com/world/detail_2011_12/16/11372558_0.shtml',
            'date': '2011-12-18'
        }
    ]
     
    for data in datas:
        es.index(index=index_name, doc_type='politics', body=data)
    
    # 3.查询所有
    result = es.search(index=index_name, doc_type='politics')
    print(result) # 返回结果会出现在 hits 字段里面,其中有 total 字段标明了查询的结果条目数,还有 max_score 代表了最大匹配分数
    
    # 4.查询指定:使用 Elasticsearch 支持的 DSL 语句
    dsl = {
        'query': {
            'match': {
                'title': '中国 领事馆'
            }
        }
    }
     
    es = Elasticsearch()
    result = es.search(index='news', doc_type='politics', body=dsl)
    print(json.dumps(result, indent=2, ensure_ascii=False))
    

插入数据

逐条插入:es.create & es.index

data = {'title': '美国留给伊拉克的是个烂摊子吗', 'url': 'http://view.news.qq.com/zt2011/usa_iraq/index.htm'}

# create写法:需要指定id
result = es.create(index=index_name, doc_type='politics', id=1, body=data)
print(result)

# index写法:无需指定id
es.index(index=index_name, doc_type='politics', body=data)

批量插入:helpers

helpers官方
Elasticsearch的bulk用法(python)
Elasticsearch - 使用Python批量写入数据

""" 批量写入数据 """
from elasticsearch import helpers
batch_size = 10000 # 每次写入的数量
for start_id in range(0, len(title_list), batch_size): # title_list为要写入的数据
	end_id = min(data_sum, start_id + batch_size)
    action = [{
        "_index": index_name,  
        "_source": {
            "title": title
        }
    } for title in title_list[start_id:end_id]]
    helpers.bulk(es, action)

查询语句DSL

官方DSL
参考

包含查询:matchmulti_match

  • match_all:默认
  • match:通用
    # match: 匹配name包含"python"关键字的数据
    body = {
        "query":{
            "match":{
                "name":"python"
            }
        }
    }
    
  • multi_match:查询可以在多个字段上执行相同的 match 查询:
    # multi_match: 在name和addr里匹配包含深圳关键字的数据
    body = {
        "query":{
            "multi_match":{
                "query":"深圳",
                "fields":["name", "addr"]
            }
        }
    }
    

等于查询term & terms

  • term:查询用户精确值,比如时间、数字,bool值和一些不可改变的词
    body = {
        "query":{
            "term":{
                "name":"python"
            }
        }
    }
    
  • terms:和 term 查询一样,但是允许指定多值进行匹配。
    # terms: 查询 xx = “xx” 或 xx = “yy”
    body = {
        "query":{
            "terms":{
                "name":["python","c++"]
            }
        }
    }
    

范围查询:range

  • range:查询找出那些落在指定区间内的数字或者时间
    body = {
        "query":{
            "range":{
                "age":{
                    "gte":18,       # >=18
                    "lte":30        # <=30
                }
            }
        }
    }
    # 查询18<=age<=30的所有数据
    

前缀查询:prefix

body = {
    "query":{
        "prefix":{
            "name":"赵"
        }
    }
}
# 查询前缀为"赵"的所有数据

通配符查询:wildcard

body = {
    "query":{
        "wildcard":{
            "name":"*id"
        }
    }
}
# 查询name以id为后缀的所有数据

排序:sort

body = {
    "query":{
        "match_all":{}
    }
    "sort":{
        "age":{                 # 根据age字段升序排序
            "order":"asc"       # asc升序,desc降序
        }
    }
}

# 多字段排序,注意顺序!写在前面的优先排序
body = {
    "query":{
        "match_all":{}
    }
    "sort":[{
        "age":{                # 先根据age字段升序排序
            "order":"asc"      # asc升序,desc降序
        }
    },{
        "name":{               # 后根据name字段升序排序
            "order":"asc"      # asc升序,desc降序
        }
    }],
}

切片式查询:from & size

body = {
    "query":{
        "match_all":{}
    }
    "from":2    # 从第二条数据开始
    "size":4    # 获取4条数据
}
# 从第2条数据开始,获取4条数据

复合查询:must & must_not & should

  • must:文档 必须 匹配这些条件才能被包含进来。
  • must_not:文档 必须不 匹配这些条件才能被包含进来。
  • should:如果满足这些语句中的任意语句,将 增加 _score ,否则,无任何影响。它们主要用于 修正每个文档的相关性得分
  • filter必须 匹配,和must比,它 不评分,只过滤。这些语句对评分没有贡献,只是根据过滤标准来排除或包含文档。
# 获取name="python"并且age=18的所有数据
body = {
    "query":{
        "bool":{
            "must":[
                {
                    "term":{
                        "name":"python"
                    }
                },
                {
                    "term":{
                        "age":18
                    }
                }
            ]
        }
    }
}

执行查询并获取该查询的匹配数:count

# 获取数据量
es.count(index="index_name",doc_type="type_name")

度量聚合:aggs

其他查询:exists & missing

  • exists & missing:被用于查找那些指定字段中有值 (exists) 或无值 (missing) 的文档。类似于isna/Not is_null 这些

常用函数

查询所有

# 方式1:
es.search(index="index_name", doc_type="type_name")
 
# 方式2:
body = {
    "query":{
        "match_all":{}
    }
}
es.search(index="index_name", doc_type="type_name", body=body)

查询数据总量

es.count(index="index_name",doc_type="type_name")

查询几条数据

rsp = es.search(index="index_name",
                 doc_type="type_name",
                 body={"query": {"match_all": {}},
                       "from": 2, # 从第二条开始
                       "size": 4  # 获取4条数据
                       })
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值