Elasticsearch DSL 是一個高階函式庫,目的是幫助編寫和執行針對 Elasticsearch 的查詢。它是建構在官方低階客戶端 (elasticsearch-py) 之上。
它提供了一種更方便、更慣用的方式來編寫和操作查詢。它與 Elasticsearch JSON DSL 非常接近,反映了它的術語和結構。它直接使用定義的類別或類似查詢集的表達式公開了 Python 的整個 DSL 範圍。
它還提供了一個可選的包裝器,用於將文件作為 Python 物件進行處理:定義映射、檢索和保存文件、將文件資料包裝在使用者定義的類別中。
要使用其他 Elasticsearch API(例如叢集運行狀況),只需使用底層客戶端。
pip 安裝elasticsearch-dsl
請參閱範例目錄以查看使用elasticsearch-dsl
的一些複雜範例。
該庫與2.x
以來的所有 Elasticsearch 版本相容,但您必須使用匹配的主要版本:
對於Elasticsearch 8.0及更高版本,請使用庫的主要版本 8 ( 8.xy
)。
對於Elasticsearch 7.0及更高版本,請使用庫的主要版本 7 ( 7.xy
)。
對於Elasticsearch 6.0及更高版本,請使用該程式庫的主要版本 6 ( 6.xy
)。
對於Elasticsearch 5.0及更高版本,請使用庫的主要版本 5 ( 5.xy
)。
對於Elasticsearch 2.0及更高版本,請使用庫的主要版本 2 ( 2.xy
)。
在 setup.py 或requirements.txt 中設定要求的建議方法是:
# Elasticsearch 8.x elasticsearch-dsl>=8.0.0,<9.0.0 # 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
開發發生在main
上,較舊的分支僅獲得錯誤修復版本
讓我們將一個典型的搜尋請求直接寫為dict
:
from elasticsearch import Elasticsearch
client = Elasticsearch ( "https://localhost:9200" )
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" }}
}
}
}
}
)
for hit in response [ 'hits' ][ 'hits' ]:
print ( hit [ '_score' ], hit [ '_source' ][ 'title' ])
for tag in response [ 'aggregations' ][ 'per_tag' ][ 'buckets' ]:
print ( tag [ 'key' ], tag [ 'max_lines' ][ 'value' ])
這種方法的問題在於它非常冗長,容易出現語法錯誤,例如不正確的嵌套,難以修改(例如添加另一個過濾器)並且編寫起來絕對不有趣。
讓我們使用 Python DSL 重寫該範例:
from elasticsearch import Elasticsearch
from elasticsearch_dsl import Search
client = Elasticsearch ( "https://localhost:9200" )
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 ()
for hit in response :
print ( hit . meta . score , hit . title )
for tag in response . aggregations . per_tag . buckets :
print ( tag . key , tag . max_lines . value )
如您所見,圖書館負責:
Query
物件(例如“match”)bool
查詢term
查詢放入bool
查詢的過濾器上下文中讓我們用一個簡單的 Python 類別來表示部落格系統中的一篇文章:
from datetime import datetime
from elasticsearch_dsl import Document , Date , Integer , Keyword , Text , connections
# Define a default Elasticsearch client
connections . create_connection ( hosts = "https://localhost:9200" )
class Article ( Document ):
title = Text ( analyzer = 'snowball' , fields = { 'raw' : Keyword ()})
body = Text ( analyzer = 'snowball' )
tags = Keyword ()
published_from = Date ()
lines = Integer ()
class Index :
name = 'blog'
settings = {
"number_of_shards" : 2 ,
}
def save ( self , ** kwargs ):
self . lines = len ( self . body . split ())
return super ( Article , self ). save ( ** kwargs )
def is_published ( self ):
return datetime . now () > self . published_from
# create the mappings in elasticsearch
Article . init ()
# create and save and article
article = 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 health
print ( connections . get_connection (). cluster . health ())
在此範例中您可以看到:
.save()
方法以掛鉤持久性生命週期您可以在文件的持久性章節中查看更多內容。
elasticsearch-py
遷移您不必移植整個應用程式來獲得 Python DSL 的好處,您可以從現有的dict
建立Search
對象,使用 API 修改它並將其序列化回dict
來逐步開始:
body = {...} # insert complicated query here
# Convert to Search object
s = Search . from_dict ( body )
# Add some filters, aggregations, queries, ...
s . filter ( "term" , tags = "python" )
# Convert back to dict to plug back into existing code
body = s . to_dict ()
啟動虛擬環境(virtualenvs):
$ virtualenv venv
$ source venv/bin/activate
若要安裝開發所需的所有依賴項,請執行:
$ pip install -e ' .[develop] '
若要執行elasticsearch-dsl-py
的所有測試,請執行:
$ python setup.py test
或者,可以使用test_elasticsearch_dsl
中的run_tests.py
腳本(它包裝了 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
將跳過test_elasticsearch_dsl/test_integration
中的測試,除非存在可以發生連線的 Elasticsearch 實例。預設情況下,根據elasticsearch-py
Connection 類別中指定的預設值,在localhost:9200
嘗試測試連線。由於執行整合測試會對 Elasticsearch 叢集造成破壞性更改,因此僅當關聯叢集為空時才執行它們。因此,如果localhost:9200
處的 Elasticsearch 實例不符合這些需求,則可以透過TEST_ES_SERVER
環境變數指定不同的測試 Elasticsearch 伺服器。
$ TEST_ES_SERVER=my-test-server:9201 ./run_tests
文件可在 https://elasticsearch-dsl.readthedocs.io 上取得。
想要破解 Elasticsearch DSL?驚人的!我們有貢獻指南。
版權所有 2013 Elasticsearch
根據 Apache 許可證 2.0 版(“許可證”)獲得許可;除非遵守許可證,否則您不得使用此文件。您可以在以下位置取得許可證副本:
http://www.apache.org/licenses/LICENSE-2.0
除非適用法律要求或書面同意,否則根據許可證分發的軟體均以「原樣」分發,不帶任何明示或暗示的保證或條件。請參閱許可證,了解許可證下管理權限和限制的特定語言。