[Elasticsearch]如何通过python操作ES数据库 pythonElasticsearch入门

[Elasticsearch]如何通过python操作ES数据库 pythonElasticsearch入门[Elasticsearch]如何通过python操作ES数据库pythonElasticsearchElasticsearch基本介绍Elasticsearch入门安装与启动python操作ES数据库连接ES数据库无用户名密码状态有密码创建索引(ES中的索引即数据库)插入数据单条数据多条数据查询数据查询结果返回参数各字段含义最直接的查询方法用body指定条件模糊查询term精确查询multi_match,多字段查询prefix,前缀查询wildcard,通配符查询regexp,正则匹配bool,多条

大家好,又见面了,我是你们的朋友全栈君。

Elasticsearch基本介绍

  • ES是一个分布式文档储存中间件,存储的方式是已序列化的JSON文档的复杂数据结构。

  • 使用倒排索引的数据结构,支持快速全文搜索。在倒排索引里列出了所有文档中出现的每一个唯一单词并分别标识了每个单词在哪一个文档中。

    • 正向索引:文档->关键词
      • 例如,搜索ABC这一字段,方法:每一行的单词逐一扫描,扫描到ABC时提取它。
    • 倒排索引:关键词->文档
      • 倒排索引表,表内的关键词对应一个倒排列表,列表内有包含该关键字的文档的DocID的集合。
  • 采用RestfulAPI标准:通过http接口使用JSON格式进行操作数据

  • 数据存储的最小单位是文档,本质上是JSON文本

图片转载,侵删
上图转载

Elasticsearch入门

安装与启动

安装与启动

python操作ES数据库

连接ES数据库

无用户名密码状态

from elasticsearch import Elasticsearch

es=Elasticsearch([{ 
   "host":"xxx.xxx.xxx.xxx","port":xxxx}])

有密码

es = Elasticsearch(['10.10.13.12'], http_auth=('xiao', '123456'), timeout=3600)

创建索引(ES中的索引即数据库)

# 创建索引(数据库)
es.indices.create(index="索引名字,字母小写")

已经存在该索引时会报错

in _raise_error
raise HTTP_EXCEPTIONS.get(status_code, TransportError)(
elasticsearch.exceptions.RequestError: RequestError(400, ‘resource_already_exists_exception’, ‘index [es_test/CvW-H_EpTK6YmcnQ7vk2Wg] already exists’

可以使用下面的语句来忽略上述错误

es.indices.create(index="es_test",ignore=400)

插入数据

单条数据

# 插入数据
body={ 
   'keyword':'测试',"content":"这是一个测试数据1"}
es.index(index='es_test',doc_type='_doc',body=body)

多条数据

#插入多条数据

doc=[{ 
   'index':{ 
   '_index':'es_zilongtest','_type':'_doc','_id':4}},
     { 
   'keyword':'食物',"content":"我喜欢吃大白菜"},
     { 
   'index': { 
   '_index': 'es_zilongtest', '_type': '_doc', '_id': 5}},
     { 
   'keyword': '食物', "content": "鸡胸肉很好吃"},
     { 
   'index':{ 
   '_index':'es_zilongtest','_type':'_doc','_id':6}},
     { 
   'keyword':'食物',"content":"小白菜也好吃"},
     ]
es.bulk(index='es_zilongtest',doc_type='_doc',body=doc)

查询数据

查询结果返回参数各字段含义

took
该命令请求花费了多长时间,单位:毫秒。

timed_out
搜索是否超时。

shards
搜索分片信息。

total
搜索分片总数。

successful
搜索成功的分片数量。

skipped
没有搜索的分片,跳过的分片。

failed
搜索失败的分片数量。

hits
搜索结果集。项目中,我们需要的一切数据都是从hits中获取。

total
返回多少条数据。

max_score
返回结果中,最大的匹配度分值。

hits
默认查询前十条数据,根据分值降序排序。

_index
索引库名称。

_type
类型名称。

_id
该条数据的id。

_score
关键字与该条数据的匹配度分值。

_source
索引库中类型,返回结果字段,不指定的话,默认全部显示出来。

参考资料ElasticSearch之查询返回结果各字段含义

最直接的查询方法

print(es.search(index='es_zilongtest'))

只需指定索引(数据库),会返回数据库中的信息

{'took': 4, 'timed_out': False, '_shards': {'total': 1, 'successful': 1, 'skipped': 0, 'failed': 0}, 'hits': {'total': {'value': 8, 'relation': 'eq'}, 'max_score': 1.0, 'hits': [{'_index': 'es_zilongtest', '_type': '_doc', '_id': 'mTZQK3wBr1SJ1UhpryaJ', '_score': 1.0, '_source': {'keyword': '测试', 'content': '这是一个测试数据'}}, {'_index': 'es_zilongtest', '_type': '_doc', '_id': 'mjZRK3wBr1SJ1UhpCSZj', '_score': 1.0, '_source': {'keyword': '测试', 'content': '这是一个测试数据1'}}, {'_index': 'es_zilongtest', '_type': '_doc', '_id': '1', '_score': 1.0, '_source': {'keyword': '动物', 'content': '大白把隶属家的小黄咬了'}}, {'_index': 'es_zilongtest', '_type': '_doc', '_id': '2', '_score': 1.0, '_source': {'keyword': '动物', 'content': '王博家里买了很多小鸡'}}, {'_index': 'es_zilongtest', '_type': '_doc', '_id': '3', '_score': 1.0, '_source': {'keyword': '动物', 'content': '王叔家的小白爱吃鸡胸肉'}}, {'_index': 'es_zilongtest', '_type': '_doc', '_id': '4', '_score': 1.0, '_source': {'keyword': '食物', 'content': '我喜欢吃大白菜'}}, {'_index': 'es_zilongtest', '_type': '_doc', '_id': '5', '_score': 1.0, '_source': {'keyword': '食物', 'content': '鸡胸肉很好吃'}}, {'_index': 'es_zilongtest', '_type': '_doc', '_id': '6', '_score': 1.0, '_source': {'keyword': '食物', 'content': '小白菜也好吃'}}]}}

这里的数据将用于后面的讲解,如有需要,请留意

常用参数

  • index – 索引名
  • q – 查询指定匹配 使用Lucene查询语法
  • from_ – 查询起始点 默认0
  • doc_type – 文档类型
  • size – 指定查询条数 默认10
  • field – 指定字段 逗号分隔
  • sort – 排序 字段:asc/desc
  • body – 使用Query DSL
  • scroll – 滚动查询

用body指定条件

# 查询数据
body ={ 
   
     'from':0, #从0开始
    'size':10 #size可以在es.search中指定,也可以在此指定,默认是10
}

print(es.search(index='es_zilongtest',body=body))

# size的另一种指定方法
es.search(index='es_python', filter_path=filter_path, body=body, size=200) 

如果觉得查出来的结果太复杂,可以设定过滤字段

# 有过滤字段查询数据
body ={ 
   
     'from':0, #从0开始
}
# 定义过滤字段,最终只显示此此段信息 hits.hits._source.写在前面 后面写你自己定义的字段名 我这里是keyword和content
filter_path=['hits.hits._source.keyword',  # keyword为第一个需要显示的字段
             'hits.hits._source.content']  # content为字段2
# print(es.search(index='es_zilongtest'))
print(es.search(index='es_zilongtest',filter_path=filter_path,body=body))

模糊查询

模糊查询需要用query命令 查询方法match 注意只能查一个字段

body ={ 
   
     'from':0,
     'query':{ 
       # 查询命令
          'match':{ 
    # 查询方法:模糊查询
               'content':'小白菜'  #content为字段名称,match这个查询方法只支持查找一个字段
          }
     }
}

filter_path=['hits.hits._source.keyword',  # 字段1
             'hits.hits._source.content']  # 字段2
# print(es.search(index='es_zilongtest'))
print(es.search(index='es_zilongtest',filter_path=filter_path,body=body))

查询结果:

{‘hits’: {‘hits’: [{’_source’: {‘keyword’: ‘食物’, ‘content’: ‘小白菜也好吃’}}, {’_source’: {‘keyword’: ‘食物’, ‘content’: ‘我喜欢吃大白菜’}}, {’_source’: {‘keyword’: ‘动物’, ‘content’: ‘大白把隶属家的小黄咬了’}}, {’_source’: {‘keyword’: ‘动物’, ‘content’: ‘王叔家的小白爱吃鸡胸肉’}}, {’_source’: {‘keyword’: ‘动物’, ‘content’: ‘王博家里买了很多小鸡’}}]}}

可以看到 content中不仅出现了小白菜 还出现了大白菜 大白 小白等内容 因为模糊查询把小白菜进行了拆分

如果不进行过滤,会看到更加详细的内容

{‘took’: 8, ‘timed_out’: False, ‘_shards’: {‘total’: 1, ‘successful’: 1, ‘skipped’: 0, ‘failed’: 0}, ‘hits’: {‘total’: {‘value’: 5, ‘relation’: ‘eq’}, ‘max_score’: 3.0320468, ‘hits’: [{’_index’: ‘es_zilongtest’, ‘_type’: ‘_doc’, ‘_id’: ‘6’, ‘_score’: 3.0320468, ‘_source’: {‘keyword’: ‘食物’, ‘content’: ‘小白菜也好吃’}}, {’_index’: ‘es_zilongtest’, ‘_type’: ‘_doc’, ‘_id’: ‘4’, ‘_score’: 2.1276836, ‘_source’: {‘keyword’: ‘食物’, ‘content’: ‘我喜欢吃大白菜’}}, {’_index’: ‘es_zilongtest’, ‘_type’: ‘_doc’, ‘_id’: ‘1’, ‘_score’: 1.2374083, ‘_source’: {‘keyword’: ‘动物’, ‘content’: ‘大白把隶属家的小黄咬了’}}, {’_index’: ‘es_zilongtest’, ‘_type’: ‘_doc’, ‘_id’: ‘3’, ‘_score’: 1.2374083, ‘_source’: {‘keyword’: ‘动物’, ‘content’: ‘王叔家的小白爱吃鸡胸肉’}}, {’_index’: ‘es_zilongtest’, ‘_type’: ‘_doc’, ‘_id’: ‘2’, ‘_score’: 0.6464764, ‘_source’: {‘keyword’: ‘动物’, ‘content’: ‘王博家里买了很多小鸡’}}]}}

其中score为关键字与该条数据的匹配度分值,默认降序排序

term 精确查询

#精确单值查询
body1={ 
   
     "query":{ 
   
          "terms":{ 
   
               "keyword.keyword":["食物","测试"] # 查询keyword="食物"或"测试"...的数据
          }
     }
}
print(es.search(index='es_zilongtest',body=body1))

注意 这里的第一个keyword是我自己设定的字段名,第二个是接口要求的必须为keyword,所以我此处可以改成

#精确多值查询
body1={ 
   
     "query":{ 
   
          "terms":{ 
   
               "content.keyword":["小白菜","大白"] # 查询keyword="小白菜"或"大白"...的数据
          }
     }
}

这样搜索结果为空,因为并没有content是小白菜或大白(文中含有这个字段也不行,必须完全相同)

multi_match,多字段查询

# 查询多个字段中都包含指定内容的数据
body3 = { 
   
    "query":{ 
   
        "multi_match":{ 
   
            "query":"小白菜",  # 指定查询内容,注意:会被分词
            "fields":["keyword", "content"]  # 指定字段
        }
    }
}
print(es.search(index='es_zilongtest',body=body3))

prefix,前缀查询

body3 = { 
   
    "query":{ 
   
        "prefix":{ 
   
            "content.keyword":"小白菜",  # 查询前缀是指定字符串的数据
        }
    }
}
# 注:英文不需要加keyword
print(es.search(index='es_zilongtest',body=body3))

wildcard,通配符查询

body = { 
   
    'query': { 
   
        'wildcard': { 
   
            'ziduan1.keyword': '?刘婵*'  # ?代表一个字符,*代表0个或多个字符
        }
    }
}
# 注:此方法只能查询单一格式的(都是英文字符串,或者都是汉语字符串)。两者混合不能查询出来。

regexp,正则匹配

body = { 
   
    'query': { 
   
        'regexp': { 
   
            'ziduan1': 'W[0-9].+'   # 使用正则表达式查询
        }
    }
}
1234567

bool,多条件查询

# must:[] 各条件之间是and的关系
body = { 

"query":{ 

"bool":{ 

'must': [{ 
"term":{ 
'ziduan1.keyword': '我爱你中国'}},
{ 
'terms': { 
'ziduan2': ['I love', 'China']}}]
}
}
}
# should: [] 各条件之间是or的关系
body = { 

"query":{ 

"bool":{ 

'should': [{ 
"term":{ 
'ziduan1.keyword': '我爱你中国'}},
{ 
'terms': { 
'ziduan2': ['I love', 'China']}}]
}
}
}
# must_not:[]各条件都不满足
body = { 

"query":{ 

"bool":{ 

'must_not': [{ 
"term":{ 
'ziduan1.keyword': '我爱你中国'}},
{ 
'terms': { 
'ziduan2': ['I love', 'China']}}]
}
}
}
# bool嵌套bool
# ziduan1、ziduan2条件必须满足的前提下,ziduan3、ziduan4满足一个即可
body = { 

"query":{ 

"bool":{ 

"must":[{ 
"term":{ 
"ziduan1":"China"}},  # 多个条件并列 ,注意:must后面是[{}, {}],[]里面的每个条件外面有个{}
{ 
"term":{ 
"ziduan2.keyword": '我爱你中国'}},
{ 
'bool': { 

'should': [
{ 
'term': { 
'ziduan3': 'Love'}},
{ 
'term': { 
'ziduan4': 'Like'}}
]
}}
]
}
}
}

说明

本文在ES数据库入门之python操作ES数据库这部分内容主要参考自参考资料1,并在其中增加了基于自身实践测试的感想,自认为对于新手可以少绕一些弯。

对于查询结果字段不理解的可以看查询数据中的查询结果返回参数各字段含义一节

参考资料:

1 python操作ES数据库

2 下一阶段阅读的内容,掌握更加详细的 Python Elasticsearch api

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/140906.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • iOS 设计模式之工厂模式

    iOS 设计模式之工厂模式

  • 计算机二级公共基础知识笔记

    计算机二级公共基础知识笔记计算机二级公共基础知识计算机系统考点一:计算机概述1.计算机的发展历程目前公认的第一台电子数字计算机是ENIAC,它于1946年在美国宾夕法尼亚大学研制成功。根据计算机本身采用的物理器件不同,将其发展分为4个阶段第一阶段是电子管计算机时代,时间为1946年到20世纪50年代第二阶段是晶体管计算机时代,时间为20世纪50年代后期到50世纪60年代中期第三阶段是中小规模集成电路计算机时代,时间是20世纪60年代中期到20世纪70年代初期第四阶段是大规模和超大规模集成电路计算机时代,时间是20

  • JQuery中的select下拉框[通俗易懂]

    JQuery中的select下拉框[通俗易懂]<select id="SelectData"><optionvalue="1">dataOne</option&

  • 最新SEO寄生虫排名

    最新SEO寄生虫排名黑帽SEO怎么做寄生虫这里说下寄生虫问题!需要的可以联系qQ325和056还有6854.对于小编来说!对寄生虫程序的选择没啥讲究!顺手好用就好!最近新出很多寄生虫!各种各样的,说得有多牛逼多牛逼的!其实都是骗人的、哪个在营销自己的产品的时候不把自己的产品说得好一些!难道会告诉大家垃圾吗?实际上市面上的虫子程序都是把原始版本改版过来的!有的把程序和菜刀软件二合一起来为了大家方便生成,看着简单易操作…

  • java冒泡排序经典代码_Java干货分享:冒泡排序

    java冒泡排序经典代码_Java干货分享:冒泡排序不管学习什么编程语言,冒泡排序都是每一个走上IT路的小伙伴的必经之路。但是还有好多小伙伴对冒泡排序摸不着头脑,今天知了堂小编就来分享一下经典算法——冒泡排序。首先咱们举个金鱼吐泡泡的例子来理解冒泡排序的过程:金鱼吐出的一连串泡泡就是我们要排序的数据,数据就像泡泡浮上水面一样一个一个被排好序,吐出的泡泡越大就会越快浮出水面,相应的,数据里某一个数字越大,那么就能越快的被排好序,当然最大的数字也是第一…

  • IntelliJ idea自定义模板Live Templates[通俗易懂]

    IntelliJ idea自定义模板Live Templates[通俗易懂]1、点击File–&gt;Setting(Ctrl+Alt+S)–&gt;Live Template,点击右侧的+号,选择Template Group2、输入MyGroup(也可以输入自定义的名称。我写的是My),然后点击OK3、选中My之后,再次点击右侧的+号,选择Live Template下图是 正确是 public static void main(String[] args)   粗心…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号