Elasticsearch DSL adalah perpustakaan tingkat tinggi yang bertujuan membantu menulis dan menjalankan kueri terhadap Elasticsearch. Itu dibangun di atas klien resmi tingkat rendah (elasticsearch-py).
Ini memberikan cara yang lebih nyaman dan idiomatis untuk menulis dan memanipulasi kueri. Itu tetap dekat dengan Elasticsearch JSON DSL, mencerminkan terminologi dan strukturnya. Ini mengekspos seluruh rentang DSL dari Python baik secara langsung menggunakan kelas yang ditentukan atau ekspresi seperti kumpulan kueri.
Ini juga menyediakan pembungkus opsional untuk bekerja dengan dokumen sebagai objek Python: mendefinisikan pemetaan, mengambil dan menyimpan dokumen, membungkus data dokumen dalam kelas yang ditentukan pengguna.
Untuk menggunakan API Elasticsearch lainnya (mis. kesehatan klaster) cukup gunakan klien yang mendasarinya.
pip instal elasticsearch-dsl
Silakan lihat direktori contoh untuk melihat beberapa contoh kompleks menggunakan elasticsearch-dsl
.
Pustaka ini kompatibel dengan semua versi Elasticsearch sejak 2.x
tetapi Anda harus menggunakan versi utama yang cocok :
Untuk Elasticsearch 8.0 dan yang lebih baru, gunakan perpustakaan versi utama 8 ( 8.xy
).
Untuk Elasticsearch 7.0 dan yang lebih baru, gunakan perpustakaan versi utama 7 ( 7.xy
).
Untuk Elasticsearch 6.0 dan yang lebih baru, gunakan perpustakaan versi utama 6 ( 6.xy
).
Untuk Elasticsearch 5.0 dan yang lebih baru, gunakan perpustakaan versi utama 5 ( 5.xy
).
Untuk Elasticsearch 2.0 dan yang lebih baru, gunakan perpustakaan versi utama 2 ( 2.xy
).
Cara yang disarankan untuk menetapkan persyaratan Anda di setup.py atau persyaratan.txt adalah:
# 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
Perkembangan terjadi di main
, cabang lama hanya mendapatkan rilis perbaikan bug
Mari kita buat permintaan pencarian biasa yang ditulis langsung sebagai 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' ])
Masalah dengan pendekatan ini adalah pendekatan ini sangat bertele-tele, rentan terhadap kesalahan sintaksis seperti penyarangan yang salah, sulit untuk dimodifikasi (misalnya menambahkan filter lain) dan jelas tidak menyenangkan untuk ditulis.
Mari kita tulis ulang contohnya menggunakan 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 )
Seperti yang Anda lihat, perpustakaan menangani:
Query
yang sesuai berdasarkan nama (mis. "cocok")bool
gabunganterm
kueri dalam konteks filter kueri bool
Mari kita buat kelas Python sederhana yang mewakili artikel dalam sistem blog:
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 ())
Dalam contoh ini Anda dapat melihat:
.save()
bawaan untuk terhubung ke siklus hidup persistensiAnda dapat melihat lebih banyak di bab persistensi dokumentasi.
elasticsearch-py
Anda tidak perlu mem-porting seluruh aplikasi Anda untuk mendapatkan manfaat dari Python DSL, Anda dapat memulai secara bertahap dengan membuat objek Search
dari dict
yang ada, memodifikasinya menggunakan API dan membuat serial kembali ke 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 ()
Aktifkan Lingkungan Virtual (virtualenvs):
$ virtualenv venv
$ source venv/bin/activate
Untuk menginstal semua dependensi yang diperlukan untuk pengembangan, jalankan:
$ pip install -e ' .[develop] '
Untuk menjalankan semua pengujian elasticsearch-dsl-py
, jalankan:
$ python setup.py test
Alternatifnya, dimungkinkan untuk menggunakan skrip run_tests.py
di test_elasticsearch_dsl
, yang membungkus pytest, untuk menjalankan subset rangkaian pengujian. Beberapa contohnya dapat dilihat dibawah ini:
# 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
akan melewatkan pengujian dari test_elasticsearch_dsl/test_integration
kecuali ada instance Elasticsearch di mana koneksi dapat terjadi. Secara default, koneksi pengujian dicoba di localhost:9200
, berdasarkan default yang ditentukan dalam kelas Connection elasticsearch-py
. Karena menjalankan pengujian integrasi akan menyebabkan perubahan yang merusak pada klaster Elasticsearch, jalankan pengujian tersebut hanya ketika klaster terkait kosong. Dengan demikian, jika instans Elasticsearch di localhost:9200
tidak memenuhi persyaratan ini, dimungkinkan untuk menentukan server pengujian Elasticsearch yang berbeda melalui variabel lingkungan TEST_ES_SERVER
.
$ TEST_ES_SERVER=my-test-server:9201 ./run_tests
Dokumentasi tersedia di https://elasticsearch-dsl.readthedocs.io.
Ingin meretas Elasticsearch DSL? Luar biasa! Kami memiliki Panduan Kontribusi.
Hak Cipta 2013 Elasticsearch
Berlisensi di bawah Lisensi Apache, Versi 2.0 ("Lisensi"); Anda tidak boleh menggunakan file ini kecuali sesuai dengan Lisensi. Anda dapat memperoleh salinan Lisensi di
http://www.apache.org/licenses/LICENSE-2.0
Kecuali diwajibkan oleh undang-undang yang berlaku atau disetujui secara tertulis, perangkat lunak yang didistribusikan berdasarkan Lisensi didistribusikan berdasarkan DASAR "APA ADANYA", TANPA JAMINAN ATAU KETENTUAN DALAM BENTUK APAPUN, baik tersurat maupun tersirat. Lihat Lisensi untuk bahasa tertentu yang mengatur izin dan batasan berdasarkan Lisensi.