ChristopherRabotin / bungiesearch

UNMAINTAINED CODE -- Elasticsearch-dsl-py django wrapper with mapping generator
BSD 3-Clause "New" or "Revised" License
67 stars 20 forks source link

Cannot request to fetch only the _id of the document #81

Closed ChristopherRabotin closed 9 years ago

ChristopherRabotin commented 9 years ago

Description

When fields is called on a Bungiesearch instance and the only parameter is _id, then map_raw_results fails to properly fetch the correct information from the database. This is problematic when requesting elasticsearch to return exactly only the IDs, or when the id field (without an underscore) is not provided when calling fields.

Example

In [3]: some_content = RawArticle.objects.bungie_content()
In [4]: for item in some_content[5:10:True]:              
    print item
   ...:     
<Result(sparrho/RawArticle/2477511): {}>
<Result(sparrho/RawArticle/2477523): {}>
<Result(sparrho/RawArticle/2477528): {}>
<Result(sparrho/RawArticle/2477491): {}>
<Result(sparrho/RawArticle/2477530): {}>
In [5]: some_content = RawArticle.objects.search.fields(['_id'])
In [6]: for item in some_content[5:10:True]:                    
    print item
   ...:     
<Result(sparrho/RawArticle/2477484): {}>
<Result(sparrho/RawArticle/2477504): {}>
<Result(sparrho/RawArticle/2477509): {}>
<Result(sparrho/RawArticle/2477511): {}>
<Result(sparrho/RawArticle/2477523): {}>
In [7]: for item in some_content[5:10:False]:
    print item
   ...:     
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-7-7541076dcf2b> in <module>()
----> 1 for item in some_content[5:10:False]:
      2     print item
      3 
/home/chris/.virtualenvs/sparrho-dj17/src/bungiesearch/bungiesearch/__init__.pyc in __getitem__(self, key)
    339         else:
    340             single_item = True
--> 341         results = super(Bungiesearch, self).__getitem__(key).execute()
    342         if single_item:
    343             try:
/home/chris/.virtualenvs/sparrho-dj17/src/bungiesearch/bungiesearch/__init__.pyc in execute(self, return_results)
    284             self.results = self.raw_results
    285         else:
--> 286             self.map_results()
    287 
    288         if return_results:
/home/chris/.virtualenvs/sparrho-dj17/src/bungiesearch/bungiesearch/__init__.pyc in map_results(self)
    293         Maps raw results and store them.
    294         '''
--> 295         self.results = Bungiesearch.map_raw_results(self.raw_results, self)
    296 
    297     def only(self, *fields):
/home/chris/.virtualenvs/sparrho-dj17/src/bungiesearch/bungiesearch/__init__.pyc in map_raw_results(cls, raw_results, instance)
    174                 results[pos] = result
    175             else:
--> 176                 model_results['{}.{}'.format(result._meta.index, model_name)].append(result.id)
    177                 found_results['{1._meta.index}.{0}.{1.id}'.format(model_name, result)] = (pos, result._meta)
    178 
/home/chris/.virtualenvs/sparrho-dj17/lib/python2.7/site-packages/elasticsearch_dsl/utils.pyc in __getattr__(self, attr_name)
    104         except KeyError:
    105             raise AttributeError(
--> 106                 '%r object has no attribute %r' % (self.__class__.__name__, attr_name))
    107 
    108     def __getitem__(self, key):
AttributeError: 'Result' object has no attribute 'id'
In [8]: dir(item)
Out[8]: ['_meta']
In [9]: dir(item._meta)
Out[9]: ['doc_type', u'id', u'index', u'score']
In [10]: 
ChristopherRabotin commented 9 years ago

Tests must check for the following bug as well:

In [13]: for k in RawArticle.objects.search.fields(['id', '_id', '_source'])[:5]:
     print k
   ....:     
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-13-dc4f6dbba33b> in <module>()
----> 1 for k in RawArticle.objects.search.fields(['id', '_id', '_source'])[:5]:
      2      print k
      3 

/home/chris/.virtualenvs/sparrho-dj17/src/bungiesearch/bungiesearch/__init__.pyc in __getitem__(self, key)
    339         else:
    340             single_item = True
--> 341         results = super(Bungiesearch, self).__getitem__(key).execute()
    342         if single_item:
    343             try:

/home/chris/.virtualenvs/sparrho-dj17/src/bungiesearch/bungiesearch/__init__.pyc in execute(self, return_results)
    284             self.results = self.raw_results
    285         else:
--> 286             self.map_results()
    287 
    288         if return_results:

/home/chris/.virtualenvs/sparrho-dj17/src/bungiesearch/bungiesearch/__init__.pyc in map_results(self)
    293         Maps raw results and store them.
    294         '''
--> 295         self.results = Bungiesearch.map_raw_results(self.raw_results, self)
    296 
    297     def only(self, *fields):

/home/chris/.virtualenvs/sparrho-dj17/src/bungiesearch/bungiesearch/__init__.pyc in map_raw_results(cls, raw_results, instance)
    182             model_idx = Bungiesearch._idx_name_to_mdl_to_mdlidx[index_name][model_name]
    183             model_obj = model_idx.get_model()
--> 184             items = model_obj.objects.filter(pk__in=ids)
    185             if instance:
    186                 if instance._only == '__model' or model_idx.optimize_queries:

/home/chris/.virtualenvs/sparrho-dj17/lib/python2.7/site-packages/django/db/models/manager.pyc in manager_method(self, *args, **kwargs)
     90         def create_method(name, method):
     91             def manager_method(self, *args, **kwargs):
---> 92                 return getattr(self.get_queryset(), name)(*args, **kwargs)
     93             manager_method.__name__ = method.__name__
     94             manager_method.__doc__ = method.__doc__

/home/chris/.virtualenvs/sparrho-dj17/lib/python2.7/site-packages/django/db/models/query.pyc in filter(self, *args, **kwargs)
    689         set.
    690         """
--> 691         return self._filter_or_exclude(False, *args, **kwargs)
    692 
    693     def exclude(self, *args, **kwargs):

/home/chris/.virtualenvs/sparrho-dj17/lib/python2.7/site-packages/django/db/models/query.pyc in _filter_or_exclude(self, negate, *args, **kwargs)
    707             clone.query.add_q(~Q(*args, **kwargs))
    708         else:
--> 709             clone.query.add_q(Q(*args, **kwargs))
    710         return clone
    711 

/home/chris/.virtualenvs/sparrho-dj17/lib/python2.7/site-packages/django/db/models/sql/query.pyc in add_q(self, q_object)
   1329         existing_inner = set(
   1330             (a for a in self.alias_map if self.alias_map[a].join_type == self.INNER))
-> 1331         clause, require_inner = self._add_q(where_part, self.used_aliases)
   1332         self.where.add(clause, AND)
   1333         for hp in having_parts:

/home/chris/.virtualenvs/sparrho-dj17/lib/python2.7/site-packages/django/db/models/sql/query.pyc in _add_q(self, q_object, used_aliases, branch_negated, current_negated)
   1356                 child_clause, needed_inner = self.build_filter(
   1357                     child, can_reuse=used_aliases, branch_negated=branch_negated,
-> 1358                     current_negated=current_negated, connector=connector)
   1359                 joinpromoter.add_votes(needed_inner)
   1360             target_clause.add(child_clause, connector)

/home/chris/.virtualenvs/sparrho-dj17/lib/python2.7/site-packages/django/db/models/sql/query.pyc in build_filter(self, filter_expr, branch_negated, current_negated, can_reuse, connector)
   1228             assert(len(targets) == 1)
   1229             col = Col(alias, targets[0], field)
-> 1230             condition = self.build_lookup(lookups, col, value)
   1231             if not condition:
   1232                 # Backwards compat for custom lookups

/home/chris/.virtualenvs/sparrho-dj17/lib/python2.7/site-packages/django/db/models/sql/query.pyc in build_lookup(self, lookups, lhs, rhs)
   1136                 final_lookup = lhs.get_lookup(lookup)
   1137                 if final_lookup:
-> 1138                     return final_lookup(lhs, rhs)
   1139                 # We didn't find a lookup, so we are going to try get_transform
   1140                 # + get_lookup('exact').

/home/chris/.virtualenvs/sparrho-dj17/lib/python2.7/site-packages/django/db/models/lookups.pyc in __init__(self, lhs, rhs)
     80     def __init__(self, lhs, rhs):
     81         self.lhs, self.rhs = lhs, rhs
---> 82         self.rhs = self.get_prep_lookup()
     83 
     84     def get_prep_lookup(self):

/home/chris/.virtualenvs/sparrho-dj17/lib/python2.7/site-packages/django/db/models/lookups.pyc in get_prep_lookup(self)
     83 
     84     def get_prep_lookup(self):
---> 85         return self.lhs.output_field.get_prep_lookup(self.lookup_name, self.rhs)
     86 
     87     def get_db_prep_lookup(self, value, connection):

/home/chris/.virtualenvs/sparrho-dj17/lib/python2.7/site-packages/django/db/models/fields/__init__.pyc in get_prep_lookup(self, lookup_type, value)
    646             return self.get_prep_value(value)
    647         elif lookup_type in ('range', 'in'):
--> 648             return [self.get_prep_value(v) for v in value]
    649         elif lookup_type == 'year':
    650             try:

/home/chris/.virtualenvs/sparrho-dj17/lib/python2.7/site-packages/django/db/models/fields/__init__.pyc in get_prep_value(self, value)
    913         if value is None:
    914             return None
--> 915         return int(value)
    916 
    917     def contribute_to_class(self, cls, name):

TypeError: int() argument must be a string or a number, not 'AttrList'