Elasticsearch的Python客户端

elasticsearch7-dsl的Python项目详细描述


Elasticsearch DSL是一个高级库,其目的是帮助编写和 对Elasticsearch运行查询。它是建立在官方之上的 低级客户端(elasticsearch-py)。在

它提供了一种更方便和惯用的编写和操作方法 查询。它与Elasticsearch的JSON DSL很接近,镜像它的 术语和结构。它公开了Python中的所有DSL 直接使用定义的类或类似queryset的表达式。在

它还提供了一个可选的包装器,用于将文档作为Python处理 对象:定义映射,检索和保存文档,包装 在用户定义的类中记录数据。在

要使用其他Elasticsearch API(例如群集运行状况),只需使用 基础客户。在

安装

pip install elasticsearch-dsl

示例

请参阅examples 目录以查看使用elasticsearch-dsl的一些复杂示例。在

兼容性

该库与2.x以来的所有Elasticsearch版本兼容,但您 必须使用匹配的主版本

对于Elasticsearch 7.0及更高版本,请使用 图书馆。在

对于Elasticsearch 6.0及更高版本,请使用 图书馆。在

对于Elasticsearch 5.0及更高版本,请使用 图书馆。在

对于Elasticsearch 2.0及更高版本,请使用 图书馆。在

在您的设置.py或 <引用>要求.txt是:

^{pr2}$

开发是在master上进行的,较旧的分支只获得错误修复版本

搜索示例

让我们将一个典型的搜索请求直接写成dict

fromelasticsearchimportElasticsearchclient=Elasticsearch()response=client.search(index="my-index",body={"query":{"bool":{"must":[{"match":{"title":"python"}}],"must_not":[{"match":{"description":"beta"}}],"filter":[{"term":{"category":"search"}}]}},"aggs":{"per_tag":{"terms":{"field":"tags"},"aggs":{"max_lines":{"max":{"field":"lines"}}}}}})forhitinresponse['hits']['hits']:print(hit['_score'],hit['_source']['title'])fortaginresponse['aggregations']['per_tag']['buckets']:print(tag['key'],tag['max_lines']['value'])

这种方法的问题是它非常冗长,容易产生语法 错误,如嵌套不正确、难以修改(例如添加另一个过滤器)和 写起来绝对不好玩。在

让我们用Python DSL重写这个示例:

fromelasticsearchimportElasticsearchfromelasticsearch_dslimportSearchclient=Elasticsearch()s=Search(using=client,index="my-index") \
    .filter("term",category="search") \
    .query("match",title="python")   \
    .exclude("match",description="beta")s.aggs.bucket('per_tag','terms',field='tags') \
    .metric('max_lines','max',field='lines')response=s.execute()forhitinresponse:print(hit.meta.score,hit.title)fortaginresponse.aggregations.per_tag.buckets:print(tag.key,tag.max_lines.value)

如你所见,图书馆负责:

  • creating appropriate ^{tt9}$ objects by name (eq. “match”)
  • composing queries into a compound ^{tt10}$ query
  • putting the ^{tt11}$ query in a filter context of the ^{tt10}$ query
  • providing a convenient access to response data
  • no curly or square brackets everywhere

持久性示例

让我们用一个简单的Python类来表示博客系统中的一篇文章:

fromdatetimeimportdatetimefromelasticsearch_dslimportDocument,Date,Integer,Keyword,Text,connections# Define a default Elasticsearch clientconnections.create_connection(hosts=['localhost'])classArticle(Document):title=Text(analyzer='snowball',fields={'raw':Keyword()})body=Text(analyzer='snowball')tags=Keyword()published_from=Date()lines=Integer()classIndex:name='blog'settings={"number_of_shards":2,}defsave(self,**kwargs):self.lines=len(self.body.split())returnsuper(Article,self).save(**kwargs)defis_published(self):returndatetime.now()>self.published_from# create the mappings in elasticsearchArticle.init()# create and save and articlearticle=Article(meta={'id':42},title='Hello world!',tags=['test'])article.body=''' looong text '''article.published_from=datetime.now()article.save()article=Article.get(id=42)print(article.is_published())# Display cluster healthprint(connections.get_connection().cluster.health())

在本例中,您可以看到:

  • providing a default connection
  • defining fields with mapping configuration
  • setting index name
  • defining custom methods
  • overriding the built-in ^{tt13}$ method to hook into the persistence life cycle
  • retrieving and saving the object into Elasticsearch
  • accessing the underlying client for other APIs

您可以在文档的持久性一章中看到更多信息。在

从^{tt14}迁移$

您不必将整个应用程序移植到 PythonDSL,可以从创建一个Search对象开始 现有的dict,使用API修改它并将其序列化回 dict

body={...}# insert complicated query here# Convert to Search objects=Search.from_dict(body)# Add some filters, aggregations, queries, ...s.filter("term",tags="python")# Convert back to dict to plug back into existing codebody=s.to_dict()

发展

激活虚拟环境(virtualenvs):

$ virtualenv venv
$ source venv/bin/activate

要安装开发所需的所有依赖项,请运行:

$ pip install -e '.[develop]'

要运行elasticsearch-dsl-py的所有测试,请运行:

$ python setup.py test

或者,可以在中使用run_tests.py脚本 test_elasticsearch_dsl,它包装了pytest,以运行测试套件的子集。一些 示例如下:

# Run all of the tests in `test_elasticsearch_dsl/test_analysis.py`
$ ./run_tests.py test_analysis.py

# Run only the `test_analyzer_serializes_as_name` test.
$ ./run_tests.py test_analysis.py::test_analyzer_serializes_as_name

pytest将跳过^{tt22}中的测试$ 除非有Elasticsearch的实例可以在其上发生连接。 默认情况下,测试连接尝试在localhost:9200,基于 在elasticsearch-pyConnection类中指定的默认值。,因为正在运行集成 测试将对Elasticsearch群集造成破坏性更改,仅运行 当关联的群集为空时。因此,如果 位于localhost:9200的Elasticsearch实例不满足这些要求, 可以通过 TEST_ES_SERVER环境变量。在

$ TEST_ES_SERVER=my-test-server:9201 ./run_tests

文件

文档可从https://elasticsearch-dsl.readthedocs.io获得。在

投稿指南

想去hac吗Elasticsearch DSL上的k?令人惊叹的!我们有Contribution-Guide。在

许可证

版权所有2013 Elasticsearch

根据Apache许可证2.0版(“许可证”)授权; 除非符合许可证,否则您不能使用此文件。 您可以在

http://www.apache.org/licenses/LICENSE-2.0

除非适用法律要求或书面同意 根据许可证分发的是“按原样”分发的, 没有任何明示或暗示的保证或条件。 有关管理权限和的特定语言,请参阅许可证 许可证下的限制。在

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java搜索大数组中的最小数   java如何将数组变量用于IF语句?   多线程如何在java中使用多核?   java实现中的数据结构单链表,无限打印输出?   java检查命令行参数是否按有效顺序传递   爪哇点火。ignite返回“网格实例未正确启动或已停止”   java如何同时使用toString()或print()等显示两个输出?   在Java中使用LinkedList列出两个多项式的加法   Java中并行流的正确使用   mac上的java Eclipse:单击Eclipse图标后崩溃,重新安装,但无法为pyDev创建视图   java如何在sqlite4java中禁用自动提交?   java这样行吗?Synchronized(线程),然后synch块中的thread=null   java方法。调用它可以接受的参数?