@@ -114,9 +114,14 @@ Here are some simple examples:
114
114
from typing import Optional
115
115
116
116
class Post (Document ):
117
- title: str # same as Text(required=True)
118
- created_at: Optional[datetime] # same as Date(required=False)
119
- published: bool # same as Boolean(required=True)
117
+ title: str # same as title = Text(required=True)
118
+ created_at: Optional[datetime] # same as created_at = Date(required=False)
119
+ published: bool # same as published = Boolean(required=True)
120
+
121
+ It is important to note that when using ``Field `` subclasses such as ``Text ``,
122
+ ``Date `` and ``Boolean ``, they must be given in the right-side of an assignment,
123
+ as shown in examples above. Using these classes as type hints will result in
124
+ errors.
120
125
121
126
Python types are mapped to their corresponding field type according to the
122
127
following table:
@@ -140,10 +145,14 @@ following table:
140
145
- ``Date(required=True) ``
141
146
* - ``date ``
142
147
- ``Date(format="yyyy-MM-dd", required=True) ``
143
-
144
- In addition to the above native types, a field can also be given a type hint
145
- of an ``InnerDoc `` subclass, in which case it becomes an ``Object `` field of
146
- that class. When the ``InnerDoc `` subclass is wrapped with ``List ``, a
148
+ * - ``InnerDocSubclass ``
149
+ - ``Object(InnerDocSubclass) ``
150
+ * - ``List(InnerDocSubclass) ``
151
+ - ``Nested(InnerDocSubclass) ``
152
+
153
+ As noted in the last two rows of the table, a field can also be given a type
154
+ hint of an ``InnerDoc `` subclass, in which case it becomes an ``Object `` field
155
+ of that class. When the ``InnerDoc `` subclass is wrapped with ``List ``, a
147
156
``Nested `` field is created instead.
148
157
149
158
.. code :: python
@@ -157,38 +166,40 @@ that class. When the ``InnerDoc`` subclass is wrapped with ``List``, a
157
166
...
158
167
159
168
class Post (Document ):
160
- address: Address # same as Object(Address)
161
- comments: List[Comment] # same as Nested(Comment)
169
+ address: Address # same as address = Object(Address)
170
+ comments: List[Comment] # same as comments = Nested(Comment)
162
171
163
172
Unfortunately it is impossible to have Python type hints that uniquely
164
173
identify every possible Elasticsearch field type. To choose a field type that
165
- is different thant the ones in the table above, the field instance can be added
174
+ is different than the ones in the table above, the field instance can be added
166
175
explicitly as a right-side assignment in the field declaration. The next
167
176
example creates a field that is typed as ``str ``, but is mapped to ``Keyword ``
168
177
instead of ``Text ``:
169
178
170
179
.. code :: python
171
180
172
181
class MyDocument (Document ):
173
- category: str = Keyword()
182
+ category: str = Keyword(required = True )
174
183
175
184
This form can also be used when additional options need to be given to
176
185
initialize the field, such as when using custom analyzer settings:
177
186
178
187
.. code :: python
179
188
180
189
class Comment (InnerDoc ):
181
- content: str = Text(analyzer = ' snowball' )
190
+ content: str = Text(analyzer = ' snowball' , required = True )
182
191
183
192
The standard ``Optional `` modifier from the Python ``typing `` package can be
184
193
used to change a typed field from required to optional. The ``List `` modifier
185
194
can be added to a field to convert it to an array, similar to using the
186
195
``multi=True `` argument on the field object.
187
196
188
197
When using type hints as above, subclasses of ``Document `` and ``InnerDoc ``
189
- inherit some of the behaviors associated with Python dataclasses. To add
190
- per-field dataclass options such as ``default `` or ``default_factory `` , the
191
- ``mapped_field() `` wrapper can be used on the right side of a typed field
198
+ inherit some of the behaviors associated with Python dataclasses, as defined by
199
+ the `PEP 681 <https://peps.python.org/pep-0681/ >`_ and the
200
+ `dataclass_transform decorator <https://typing.readthedocs.io/en/latest/spec/dataclasses.html#dataclass-transform >`_.
201
+ To add per-field dataclass options such as ``default `` or ``default_factory ``,
202
+ the ``mapped_field() `` wrapper can be used on the right side of a typed field
192
203
declaration:
193
204
194
205
.. code :: python
@@ -197,7 +208,11 @@ declaration:
197
208
title: str = mapped_field(default = " no title" )
198
209
created_at: datetime = mapped_field(default_factory = datetime.now)
199
210
published: bool = mapped_field(default = False )
200
- category: str = mapped_field(Keyword(), default = " general" )
211
+ category: str = mapped_field(Keyword(required = True ), default = " general" )
212
+
213
+ When using the ``mapped_field() `` wrapper function, an explicit field type
214
+ instance can be passed as a first positional argument, as the ``category ``
215
+ field does in the example above.
201
216
202
217
Static type checkers such as `mypy <https://mypy-lang.org/ >`_ and
203
218
`pyright <https://github.com/microsoft/pyright >`_ can use the type hints and
@@ -210,15 +225,15 @@ using fields as class attributes. Consider the following example:
210
225
.. code :: python
211
226
212
227
class MyDocument (Document ):
213
- title: str = mapped_field( default = " no title " )
228
+ title: str
214
229
215
230
doc = MyDocument()
216
231
# doc.title is typed as "str" (correct)
217
232
# MyDocument.title is also typed as "str" (incorrect)
218
233
219
234
To help type checkers correctly identify class attributes as such, the ``M ``
220
235
generic must be used as a wrapper to the type hint, as shown in the next
221
- example :
236
+ examples :
222
237
223
238
.. code :: python
224
239
@@ -230,10 +245,13 @@ example:
230
245
231
246
doc = MyDocument()
232
247
# doc.title is typed as "str"
248
+ # doc.created_at is typed as "datetime"
233
249
# MyDocument.title is typed as "InstrumentedField"
250
+ # MyDocument.created_at is typed as "InstrumentedField"
234
251
235
- Note that the ``M `` type hint does not provide any runtime behavior, it just
236
- provides additional typing declarations for type checkers.
252
+ Note that the ``M `` type hint does not provide any runtime behavior and its use
253
+ is not required, but it can be useful to eliminate spurious type errors in IDEs
254
+ or type checking builds.
237
255
238
256
The ``InstrumentedField `` objects returned when fields are accessed as class
239
257
attributes are proxies for the field instances that can be used anywhere a
@@ -245,6 +263,9 @@ field needs to be referenced, such as when specifying sort options in a
245
263
# sort by creation date descending, and title ascending
246
264
s = MyDocument.search().sort(- MyDocument.created_at, MyDocument.title)
247
265
266
+ When specifying sorting order, the ``+ `` and ``- `` unary operators can be used
267
+ on the class field attributes to indicate ascending and descending order.
268
+
248
269
Note on dates
249
270
~~~~~~~~~~~~~
250
271
0 commit comments