Skip to content

Commit f7f0795

Browse files
committed
Rename default do_type name to doc
1 parent 0d7e1df commit f7f0795

File tree

9 files changed

+97
-88
lines changed

9 files changed

+97
-88
lines changed

docs/persistence.rst

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ layer for your application.
99
Mappings
1010
--------
1111

12-
The mapping definition follows a similar pattern to the query dsl:
12+
If you wish to create mappings manually you can use the ``Mapping`` class, for
13+
more advanced use cases, however, we recommend you use the :ref:`doc_type`
14+
abstraction in combination with :ref:`index` (or ``IndexTemplate``) to define
15+
index-level settings and properties. The mapping definition follows a similar
16+
pattern to the query dsl:
1317

1418
.. code:: python
1519
@@ -101,6 +105,8 @@ specify type (``nGram`` in our example).
101105
either not exist or be closed. To create multiple ``DocType``-defined
102106
mappings you can use the :ref:`index` object.
103107

108+
.. _doc_type:
109+
104110
DocType
105111
-------
106112

@@ -198,7 +204,7 @@ explicitly:
198204
first.save()
199205
200206
201-
All the metadata fields (``id``, ``parent``, ``routing``, ``index`` etc) can be
207+
All the metadata fields (``id``, ``routing``, ``index`` etc) can be
202208
accessed (and set) via a ``meta`` attribute or directly using the underscored
203209
variant:
204210

@@ -270,16 +276,12 @@ accessed through the ``_doc_type`` attribute of the class:
270276

271277
.. code:: python
272278
273-
# name of the type and index in elasticsearch
274-
Post._doc_type.name
279+
# name of the index in elasticsearch
275280
Post._doc_type.index
276281
277282
# the raw Mapping object
278283
Post._doc_type.mapping
279284
280-
# the optional name of the parent type (if defined)
281-
Post._doc_type.parent
282-
283285
The ``_doc_type`` attribute is also home to the ``refresh`` method which will
284286
update the mapping on the ``DocType`` from elasticsearch. This is very useful
285287
if you use dynamic mappings and want the class to be aware of those fields (for
@@ -351,8 +353,8 @@ In the ``Meta`` class inside your document definition you can define various
351353
metadata for your document:
352354

353355
``doc_type``
354-
name of the doc_type in elasticsearch. By default it will be constructed from
355-
the class name (MyDocument -> my_document)
356+
name of the doc_type in elasticsearch. By default it will be set to ``doc``,
357+
it is not recommended to change.
356358

357359
``index``
358360
default index for the document, by default it is empty and every operation
@@ -366,7 +368,7 @@ metadata for your document:
366368
created from the fields on the document class itself.
367369

368370
Any attributes on the ``Meta`` class that are instance of ``MetaField`` will be
369-
used to control the mapping of the meta fields (``_all``, ``_parent`` etc).
371+
used to control the mapping of the meta fields (``_all``, ``dynamic`` etc).
370372
Just name the parameter (without the leading underscore) as the field you wish
371373
to map and pass any parameters to the ``MetaField`` class:
372374

@@ -377,7 +379,6 @@ to map and pass any parameters to the ``MetaField`` class:
377379
378380
class Meta:
379381
all = MetaField(enabled=False)
380-
parent = MetaField(type='blog')
381382
dynamic = MetaField('strict')
382383
383384
.. _index:

elasticsearch_dsl/document.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,8 @@ def __init__(self, name, bases, attrs):
3535
# default cluster alias, can be overriden in doc.meta
3636
self._using = getattr(meta, 'using', None)
3737

38-
# get doc_type name, if not defined take the name of the class and
39-
# transform it to lower_case
40-
doc_type = getattr(meta, 'doc_type',
41-
re.sub(r'(.)([A-Z])', r'\1_\2', name).lower())
38+
# get doc_type name, if not defined use 'doc'
39+
doc_type = getattr(meta, 'doc_type', 'doc')
4240

4341
# create the mapping instance
4442
self.mapping = getattr(meta, 'mapping', Mapping(doc_type))
@@ -63,6 +61,9 @@ def __init__(self, name, bases, attrs):
6361
self._using = self._using or b._doc_type._using
6462
self.index = self.index or b._doc_type.index
6563

64+
# custom method to determine if a hit belongs to this DocType
65+
self._matches = getattr(meta, 'matches', None)
66+
6667
@property
6768
def using(self):
6869
return self._using or 'default'
@@ -86,6 +87,14 @@ def init(self, index=None, using=None):
8687
def refresh(self, index=None, using=None):
8788
self.mapping.update_from_es(index or self.index, using=using or self.using)
8889

90+
def matches(self, hit):
91+
print(self.index, self.name, hit)
92+
if self._matches is not None:
93+
return self._matches(hit)
94+
95+
print(self.index, self.name, hit)
96+
return (self.index is None or self.index == hit.get('_index')) and self.name == hit.get('_type')
97+
8998
@add_metaclass(DocTypeMeta)
9099
class InnerDoc(ObjectBase):
91100
"""

elasticsearch_dsl/response/__init__.py

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from six import itervalues
2-
31
from ..utils import AttrDict, AttrList
42

53
from .hit import Hit, HitMeta
@@ -40,46 +38,13 @@ def __setstate__(self, state):
4038
def success(self):
4139
return self._shards.total == self._shards.successful and not self.timed_out
4240

43-
def _resolve_nested(self, field, doc_class):
44-
if hasattr(self._doc_class, '_doc_type'):
45-
nested_field = self._doc_class._doc_type.resolve_field(field)
46-
47-
else:
48-
for dt in itervalues(self._search._doc_type_map):
49-
if not hasattr(dt, '_doc_type'):
50-
continue
51-
nested_field = dt._doc_type.resolve_field(field)
52-
if nested_field is not None:
53-
break
54-
55-
if nested_field is not None:
56-
return nested_field._doc_class
57-
58-
return doc_class
59-
60-
def _get_result(self, hit):
61-
doc_class = Hit
62-
dt = hit.get('_type')
63-
64-
if '_nested' in hit:
65-
doc_class = self._resolve_nested(hit['_nested']['field'], doc_class)
66-
67-
elif dt in self._search._doc_type_map:
68-
doc_class = self._search._doc_type_map[dt]
69-
70-
for t in hit.get('inner_hits', ()):
71-
hit['inner_hits'][t] = Response(self._search, hit['inner_hits'][t], doc_class=doc_class)
72-
73-
callback = getattr(doc_class, 'from_es', doc_class)
74-
return callback(hit)
75-
7641
@property
7742
def hits(self):
7843
if not hasattr(self, '_hits'):
7944
h = self._d_['hits']
8045

8146
try:
82-
hits = AttrList(map(self._get_result, h['hits']))
47+
hits = AttrList(map(self._search._get_result, h['hits']))
8348
except AttributeError as e:
8449
# avoid raising AttributeError since it will be hidden by the property
8550
raise TypeError("Could not parse hits.", e)

elasticsearch_dsl/search.py

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,12 @@ def __init__(self, using='default', index=None, doc_type=None, extra=None):
9292
self._doc_type = []
9393
self._doc_type_map = {}
9494
if isinstance(doc_type, (tuple, list)):
95-
for dt in doc_type:
96-
self._add_doc_type(dt)
95+
self._doc_type.extend(doc_type)
9796
elif isinstance(doc_type, collections.Mapping):
9897
self._doc_type.extend(doc_type.keys())
9998
self._doc_type_map.update(doc_type)
10099
elif doc_type:
101-
self._add_doc_type(doc_type)
100+
self._doc_type.append(doc_type)
102101

103102
self._params = {}
104103
self._extra = extra or {}
@@ -159,11 +158,52 @@ def index(self, *index):
159158

160159
return s
161160

162-
def _add_doc_type(self, doc_type):
163-
if hasattr(doc_type, '_doc_type'):
164-
self._doc_type_map[doc_type._doc_type.name] = doc_type
165-
doc_type = doc_type._doc_type.name
166-
self._doc_type.append(doc_type)
161+
def _get_doc_type(self):
162+
"""
163+
Return a list of doc_type names to be used
164+
"""
165+
return list(set(dt._doc_type.name if hasattr(dt, '_doc_type') else dt for dt in self._doc_type))
166+
167+
def _resolve_nested(self, field, parent_class=None):
168+
doc_class = Hit
169+
if hasattr(parent_class, '_doc_type'):
170+
nested_field = parent_class._doc_type.resolve_field(field)
171+
172+
else:
173+
for dt in self._doc_type:
174+
if not hasattr(dt, '_doc_type'):
175+
continue
176+
nested_field = dt._doc_type.resolve_field(field)
177+
if nested_field is not None:
178+
break
179+
180+
if nested_field is not None:
181+
return nested_field._doc_class
182+
183+
return doc_class
184+
185+
def _get_result(self, hit, parent_class=None):
186+
doc_class = Hit
187+
dt = hit.get('_type')
188+
189+
if '_nested' in hit:
190+
doc_class = self._resolve_nested(hit['_nested']['field'], parent_class)
191+
192+
elif dt in self._doc_type_map:
193+
doc_class = self._doc_type_map[dt]
194+
195+
else:
196+
for doc_type in self._doc_type:
197+
if hasattr(doc_type, '_doc_type') and doc_type._doc_type.matches(hit):
198+
doc_class = doc_type
199+
break
200+
201+
for t in hit.get('inner_hits', ()):
202+
hit['inner_hits'][t] = Response(self, hit['inner_hits'][t], doc_class=doc_class)
203+
204+
callback = getattr(doc_class, 'from_es', doc_class)
205+
return callback(hit)
206+
167207

168208
def doc_type(self, *doc_type, **kwargs):
169209
"""
@@ -186,8 +226,7 @@ def doc_type(self, *doc_type, **kwargs):
186226
s._doc_type = []
187227
s._doc_type_map = {}
188228
else:
189-
for dt in doc_type:
190-
s._add_doc_type(dt)
229+
s._doc_type.extend(doc_type)
191230
s._doc_type.extend(kwargs.keys())
192231
s._doc_type_map.update(kwargs)
193232
return s
@@ -528,6 +567,7 @@ def highlight(self, *fields, **kwargs):
528567
Search().highlight('title', fragment_size=50).highlight('body', fragment_size=100)
529568
530569
which will produce::
570+
531571
{
532572
"highlight": {
533573
"fields": {
@@ -615,7 +655,7 @@ def count(self):
615655
# TODO: failed shards detection
616656
return es.count(
617657
index=self._index,
618-
doc_type=self._doc_type,
658+
doc_type=self._get_doc_type(),
619659
body=d,
620660
**self._params
621661
)['count']
@@ -634,7 +674,7 @@ def execute(self, ignore_cache=False):
634674
self,
635675
es.search(
636676
index=self._index,
637-
doc_type=self._doc_type,
677+
doc_type=self._get_doc_type(),
638678
body=self.to_dict(),
639679
**self._params
640680
)
@@ -657,12 +697,10 @@ def scan(self):
657697
es,
658698
query=self.to_dict(),
659699
index=self._index,
660-
doc_type=self._doc_type,
700+
doc_type=self._get_doc_type(),
661701
**self._params
662702
):
663-
callback = self._doc_type_map.get(hit['_type'], Hit)
664-
callback = getattr(callback, 'from_es', callback)
665-
yield callback(hit)
703+
yield self._get_result(hit)
666704

667705
def delete(self):
668706
"""
@@ -675,7 +713,7 @@ def delete(self):
675713
es.delete_by_query(
676714
index=self._index,
677715
body=self.to_dict(),
678-
doc_type=self._doc_type,
716+
doc_type=self._get_doc_type(),
679717
**self._params
680718
)
681719
)
@@ -720,7 +758,7 @@ def to_dict(self):
720758
if s._index:
721759
meta['index'] = s._index
722760
if s._doc_type:
723-
meta['type'] = s._doc_type
761+
meta['type'] = s._get_doc_type()
724762
meta.update(s._params)
725763

726764
out.append(meta)
@@ -737,7 +775,7 @@ def execute(self, ignore_cache=False, raise_on_error=True):
737775

738776
responses = es.msearch(
739777
index=self._index,
740-
doc_type=self._doc_type,
778+
doc_type=self._get_doc_type(),
741779
body=self.to_dict(),
742780
**self._params
743781
)

test_elasticsearch_dsl/test_document.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ def test_custom_field():
8989

9090
def test_custom_field_mapping():
9191
assert {
92-
'secret_doc': {
92+
'doc': {
9393
'properties': {
9494
'title': {'index': 'no', 'type': 'text'}
9595
}
@@ -186,7 +186,7 @@ class Meta:
186186
dynamic_templates = document.MetaField([42])
187187

188188
assert {
189-
'user': {
189+
'doc': {
190190
'properties': {
191191
'username': {'type': 'text'}
192192
},
@@ -277,9 +277,8 @@ def test_to_dict_ignores_empty_collections():
277277
def test_declarative_mapping_definition():
278278
assert issubclass(MyDoc, document.DocType)
279279
assert hasattr(MyDoc, '_doc_type')
280-
assert 'my_doc' == MyDoc._doc_type.name
281280
assert {
282-
'my_doc': {
281+
'doc': {
283282
'properties': {
284283
'created_at': {'type': 'date'},
285284
'name': {'type': 'text'},
@@ -368,13 +367,11 @@ def test_meta_inheritance():
368367
assert issubclass(MyMultiSubDoc, MyDoc2)
369368
assert issubclass(MyMultiSubDoc, document.DocType)
370369
assert hasattr(MyMultiSubDoc, '_doc_type')
371-
# doc_type should not be inherited
372-
assert 'my_multi_sub_doc' == MyMultiSubDoc._doc_type.name
373370
# index and using should be
374371
assert MyMultiSubDoc._doc_type.index == MySubDoc._doc_type.index
375372
assert MyMultiSubDoc._doc_type.using == MySubDoc._doc_type.using
376373
assert {
377-
'my_multi_sub_doc': {
374+
'doc': {
378375
'properties': {
379376
'created_at': {'type': 'date'},
380377
'name': {'type': 'keyword'},

test_elasticsearch_dsl/test_index.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def test_registered_doc_type_included_in_to_dict():
6464
assert Post._doc_type.index == 'i'
6565
assert {
6666
'mappings': {
67-
'post': {
67+
'doc': {
6868
'properties': {
6969
'title': {'type': 'text'},
7070
'published_from': {'type': 'date'},
@@ -79,7 +79,7 @@ def test_registered_doc_type_included_in_search():
7979

8080
s = i.search()
8181

82-
assert s._doc_type_map == {'post': Post}
82+
assert s._doc_type == [Post]
8383

8484

8585
def test_aliases_add_to_object():

0 commit comments

Comments
 (0)