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


文章目录

  • 和DB对应关系
  • 安装:以7.14.0版本为例
  • 基础python函数
  • 创建index:`es.indices.create`
  • 删除index:`es.indices.delete`
  • 更新数据:`es.update`
  • 删除数据:`es.delete`
  • 查询数据:`es.search` & `es.get`
  • 插入数据
  • 逐条插入:`es.create` & `es.index`
  • 批量插入:`helpers`
  • 查询语句DSL
  • 包含查询:`match`与`multi_match`
  • 等于查询`term` & `terms`
  • 范围查询:`range`
  • 前缀查询:`prefix`
  • 通配符查询:`wildcard`
  • 排序:`sort`
  • 切片式查询:`from` & `size`
  • 复合查询:`must` & `must_not` & `should`
  • 执行查询并获取该查询的匹配数:`count`
  • 度量聚合:`aggs`
  • 其他查询:`exists` & `missing`
  • 常用函数
  • 查询所有
  • 查询数据总量
  • 查询几条数据


和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条数据
                       })