用于ElasticSearch的Python客户端
elasticsearch-dsl的Python项目详细描述
ElasticSearchDSL是一个高级库,其目标是帮助编写和 对ElasticSearch运行查询。它是建立在官方之上的 低级客户端(elasticsearch-py)。
它提供了一种更方便、更惯用的方式来编写和操作 询问。它与elasticsearch的json dsl很接近,反映了它的 术语和结构。它公开了python中dsl的整个范围 直接使用定义的类或类查询集表达式。
它还提供了一个可选的包装器,用于将文档用作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及更高版本,请使用 图书馆。
在setup.py中设置需求的推荐方法 requirements.txt是:
# Elasticsearch 7.x elasticsearch-dsl>=7.0.0,<8.0.0 # Elasticsearch 6.x elasticsearch-dsl>=6.0.0,<7.0.0 # Elasticsearch 5.x elasticsearch-dsl>=5.0.0,<6.0.0 # Elasticsearch 2.x elasticsearch-dsl>=2.0.0,<3.0.0
开发是在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
您可以在文档的持久性一章中看到更多内容。
从elasticsearch-py
迁移您不必移植整个应用程序即可获得 python dsl,您可以从 现有的^ {TT8}$,使用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
或者,也可以在 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
贡献指南
想要hac弹性搜索DSL上的K?令人惊叹的!我们有Contribution-Guide。
许可证
2013 ElasticSearch版权所有
根据apache许可证2.0版(以下简称“许可证”)授权; 除非符合许可证,否则您不能使用此文件。 您可以在
http://www.apache.org/licenses/LICENSE-2.0
除非适用法律要求或书面同意,否则软件 根据许可证分发是按“原样”分发的, 没有任何保证或条件,无论是明示或暗示。 查看管理权限的特定语言的许可证 许可下的限制。