Skip to content

Commit 4c67466

Browse files
committedOct 26, 2015
Have README be the file and README.rst the link
1 parent efeb52f commit 4c67466

File tree

2 files changed

+213
-213
lines changed

2 files changed

+213
-213
lines changed
 

‎README

-1
This file was deleted.

‎README

+212
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
Elasticsearch DSL
2+
=================
3+
4+
Elasticsearch DSL is a high-level library whose aim is to help with writing and
5+
running queries against Elasticsearch. It is built on top of the official
6+
low-level client (``elasticsearch-py``).
7+
8+
It provides a more convenient and idiomatic way to write and manipulate
9+
queries. It stays close to the Elasticsearch JSON DSL, mirroring its
10+
terminology and structure. It exposes the whole range of the DSL from Python
11+
either directly using defined classes or a queryset-like expressions.
12+
13+
It also provides an optional wrapper for working with documents as Python
14+
objects: defining mappings, retrieving and saving documents, wrapping the
15+
document data in user-defined classes.
16+
17+
To use the other Elasticsearch APIs (eg. cluster health) just use the
18+
underlying client.
19+
20+
Search Example
21+
--------------
22+
23+
Let's have a typical search request written directly as a ``dict``:
24+
25+
.. code:: python
26+
27+
from elasticsearch import Elasticsearch
28+
client = Elasticsearch()
29+
30+
response = client.search(
31+
index="my-index",
32+
body={
33+
"query": {
34+
"filtered": {
35+
"query": {
36+
"bool": {
37+
"must": [{"match": {"title": "python"}}],
38+
"must_not": [{"match": {"description": "beta"}}]
39+
}
40+
},
41+
"filter": {"term": {"category": "search"}}
42+
}
43+
},
44+
"aggs" : {
45+
"per_tag": {
46+
"terms": {"field": "tags"},
47+
"aggs": {
48+
"max_lines": {"max": {"field": "lines"}}
49+
}
50+
}
51+
}
52+
}
53+
)
54+
55+
for hit in response['hits']['hits']:
56+
print(hit['_score'], hit['_source']['title'])
57+
58+
for tag in response['aggregations']['per_tag']['buckets']:
59+
print(tag['key'], tag['max_lines']['value'])
60+
61+
62+
63+
The problem with this approach is that it is very verbose, prone to syntax
64+
mistakes like incorrect nesting, hard to modify (eg. adding another filter) and
65+
definitely not fun to write.
66+
67+
Let's rewrite the example using the Python DSL:
68+
69+
.. code:: python
70+
71+
from elasticsearch import Elasticsearch
72+
from elasticsearch_dsl import Search, Q
73+
74+
client = Elasticsearch()
75+
76+
s = Search(using=client, index="my-index") \
77+
.filter("term", category="search") \
78+
.query("match", title="python") \
79+
.query(~Q("match", description="beta"))
80+
81+
s.aggs.bucket('per_tag', 'terms', field='tags') \
82+
.metric('max_lines', 'max', field='lines')
83+
84+
response = s.execute()
85+
86+
for hit in response:
87+
print(hit.meta.score, hit.title)
88+
89+
for tag in response.aggregations.per_tag.buckets:
90+
print(tag.key, tag.max_lines.value)
91+
92+
As you see, the library took care of:
93+
94+
* creating appropriate ``Query`` objects by name (eq. "match")
95+
96+
* composing queries into a compound ``bool`` query
97+
98+
* creating a ``filtered`` query since ``.filter()`` was used
99+
100+
* providing a convenient access to response data
101+
102+
* no curly or square brackets everywhere
103+
104+
105+
Persistence Example
106+
-------------------
107+
108+
Let's have a simple Python class representing an article in a blogging system:
109+
110+
.. code:: python
111+
112+
from datetime import datetime
113+
from elasticsearch_dsl import DocType, String, Date, Integer
114+
from elasticsearch_dsl.connections import connections
115+
116+
# Define a default Elasticsearch client
117+
connections.create_connection(hosts=['localhost'])
118+
119+
class Article(DocType):
120+
title = String(analyzer='snowball', fields={'raw': String(index='not_analyzed')})
121+
body = String(analyzer='snowball')
122+
tags = String(index='not_analyzed')
123+
published_from = Date()
124+
lines = Integer()
125+
126+
class Meta:
127+
index = 'blog'
128+
129+
def save(self, ** kwargs):
130+
self.lines = len(self.body.split())
131+
return super(Article, self).save(** kwargs)
132+
133+
def is_published(self):
134+
return datetime.now() < self.published_from
135+
136+
# create the mappings in elasticsearch
137+
Article.init()
138+
139+
# create and save and article
140+
article = Article(meta={'id': 42}, title='Hello world!', tags=['test'])
141+
article.body = ''' looong text '''
142+
article.published_from = datetime.now()
143+
article.save()
144+
145+
article = Article.get(id=42)
146+
print(article.is_published())
147+
148+
# Display cluster health
149+
print(connections.get_connection().cluster.health())
150+
151+
152+
In this example you can see:
153+
154+
* providing a default connection
155+
156+
* defining fields with mapping configuration
157+
158+
* setting index name
159+
160+
* defining custom methods
161+
162+
* overriding the built-in ``.save()`` method to hook into the persistence
163+
life cycle
164+
165+
* retrieving and saving the object into Elasticsearch
166+
167+
* accessing the underlying client for other APIs
168+
169+
You can see more in the persistence chapter of the documentation.
170+
171+
Migration from ``elasticsearch-py``
172+
-----------------------------------
173+
174+
You don't have to port your entire application to get the benefits of the
175+
Python DSL, you can start gradually by creating a ``Search`` object from your
176+
existing ``dict``, modifying it using the API and serializing it back to a
177+
``dict``:
178+
179+
.. code:: python
180+
181+
body = {...} # insert complicated query here
182+
183+
# Convert to Search object
184+
s = Search.from_dict(body)
185+
186+
# Add some filters, aggregations, queries, ...
187+
s.filter("term", tags="python")
188+
189+
# Convert back to dict to plug back into existing code
190+
body = s.to_dict()
191+
192+
Documentation
193+
-------------
194+
195+
Documentation is available at https://elasticsearch-dsl.readthedocs.org.
196+
197+
License
198+
-------
199+
200+
Copyright 2013 Elasticsearch
201+
202+
Licensed under the Apache License, Version 2.0 (the "License");
203+
you may not use this file except in compliance with the License.
204+
You may obtain a copy of the License at
205+
206+
http://www.apache.org/licenses/LICENSE-2.0
207+
208+
Unless required by applicable law or agreed to in writing, software
209+
distributed under the License is distributed on an "AS IS" BASIS,
210+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
211+
See the License for the specific language governing permissions and
212+
limitations under the License.

‎README.rst

-212
This file was deleted.

‎README.rst

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
README

0 commit comments

Comments
 (0)
Please sign in to comment.