Refactoring: Simple is better than complex

Signed-off-by: Wilson Júnior <wilsonpjunior@gmail.com>
This commit is contained in:
Wilson Júnior 2014-11-29 23:48:58 -02:00
parent 80f80cd31f
commit 2b3bb81fae
3 changed files with 20 additions and 28 deletions

View File

@ -68,7 +68,7 @@ class BaseDocument(object):
# Exception. # Exception.
if not self._dynamic: if not self._dynamic:
for var in values.keys(): for var in values.keys():
if var not in self._fields.keys() + ['id', 'pk', '_cls']: if var not in self._fields.keys() + ['id', 'pk', '_cls', '_text_score']:
msg = ( msg = (
"The field '{0}' does not exist on the document '{1}'" "The field '{0}' does not exist on the document '{1}'"
).format(var, self._class_name) ).format(var, self._class_name)
@ -281,6 +281,16 @@ class BaseDocument(object):
""" """
pass pass
def get_text_score(self):
"""
Get text score from text query
"""
if '_text_score' not in self._data:
raise InvalidDocumentError('This document is not originally built from a text query')
return self._data['_text_score']
def to_mongo(self, use_db_field=True, fields=[]): def to_mongo(self, use_db_field=True, fields=[]):
""" """
Return as SON data ready for use with MongoDB. Return as SON data ready for use with MongoDB.

View File

@ -6,7 +6,6 @@ import operator
import pprint import pprint
import re import re
import warnings import warnings
import types
from bson import SON from bson import SON
from bson.code import Code from bson.code import Code
@ -38,8 +37,6 @@ PULL = 4
RE_TYPE = type(re.compile('')) RE_TYPE = type(re.compile(''))
def get_text_score(doc):
return doc._data.get('_text_score')
class BaseQuerySet(object): class BaseQuerySet(object):
@ -69,7 +66,6 @@ class BaseQuerySet(object):
self._as_pymongo = False self._as_pymongo = False
self._as_pymongo_coerce = False self._as_pymongo_coerce = False
self._search_text = None self._search_text = None
self._include_text_scores = False
# If inheritance is allowed, only return instances and instances of # If inheritance is allowed, only return instances and instances of
# subclasses of the class being used # subclasses of the class being used
@ -161,14 +157,9 @@ class BaseQuerySet(object):
if queryset._as_pymongo: if queryset._as_pymongo:
return queryset._get_as_pymongo(queryset._cursor[key]) return queryset._get_as_pymongo(queryset._cursor[key])
doc = queryset._document._from_son(queryset._cursor[key], return queryset._document._from_son(queryset._cursor[key],
_auto_dereference=self._auto_dereference, only_fields=self.only_fields) _auto_dereference=self._auto_dereference, only_fields=self.only_fields)
if self._include_text_scores:
doc.get_text_score = types.MethodType(get_text_score, doc)
return doc
raise AttributeError raise AttributeError
def __iter__(self): def __iter__(self):
@ -201,7 +192,7 @@ class BaseQuerySet(object):
""" """
return self.__call__(*q_objs, **query) return self.__call__(*q_objs, **query)
def search_text(self, text, language=None, include_text_scores=True): def search_text(self, text, language=None):
""" """
Start a text search, using text indexes. Start a text search, using text indexes.
Require: MongoDB server version 2.6+. Require: MongoDB server version 2.6+.
@ -210,14 +201,11 @@ class BaseQuerySet(object):
for the search and the rules for the stemmer and tokenizer. for the search and the rules for the stemmer and tokenizer.
If not specified, the search uses the default language of the index. If not specified, the search uses the default language of the index.
For supported languages, see `Text Search Languages <http://docs.mongodb.org/manual/reference/text-search-languages/#text-search-languages>`. For supported languages, see `Text Search Languages <http://docs.mongodb.org/manual/reference/text-search-languages/#text-search-languages>`.
:param include_text_scores: If True, automatically add a get_text_score method to Document.
""" """
queryset = self.clone() queryset = self.clone()
if queryset._search_text: if queryset._search_text:
raise OperationError( raise OperationError(
"Is not possible to use search_text two times.") "It is not possible to use search_text two times.")
query_kwargs = SON({'$search': text}) query_kwargs = SON({'$search': text})
if language: if language:
@ -227,7 +215,6 @@ class BaseQuerySet(object):
queryset._mongo_query = None queryset._mongo_query = None
queryset._cursor_obj = None queryset._cursor_obj = None
queryset._search_text = text queryset._search_text = text
queryset._include_text_scores = include_text_scores
return queryset return queryset
@ -684,7 +671,7 @@ class BaseQuerySet(object):
'_timeout', '_class_check', '_slave_okay', '_read_preference', '_timeout', '_class_check', '_slave_okay', '_read_preference',
'_iter', '_scalar', '_as_pymongo', '_as_pymongo_coerce', '_iter', '_scalar', '_as_pymongo', '_as_pymongo_coerce',
'_limit', '_skip', '_hint', '_auto_dereference', '_limit', '_skip', '_hint', '_auto_dereference',
'_search_text', '_include_text_scores', 'only_fields', '_max_time_ms') '_search_text', 'only_fields', '_max_time_ms')
for prop in copy_props: for prop in copy_props:
val = getattr(self, prop) val = getattr(self, prop)
@ -1351,9 +1338,6 @@ class BaseQuerySet(object):
doc = self._document._from_son(raw_doc, doc = self._document._from_son(raw_doc,
_auto_dereference=self._auto_dereference, only_fields=self.only_fields) _auto_dereference=self._auto_dereference, only_fields=self.only_fields)
if self._include_text_scores:
doc.get_text_score = types.MethodType(get_text_score, doc)
if self._scalar: if self._scalar:
return self._get_scalar(doc) return self._get_scalar(doc)
@ -1362,6 +1346,7 @@ class BaseQuerySet(object):
def rewind(self): def rewind(self):
"""Rewind the cursor to its unevaluated state. """Rewind the cursor to its unevaluated state.
.. versionadded:: 0.3 .. versionadded:: 0.3
""" """
self._iter = False self._iter = False
@ -1389,7 +1374,7 @@ class BaseQuerySet(object):
if self._loaded_fields: if self._loaded_fields:
cursor_args['fields'] = self._loaded_fields.as_dict() cursor_args['fields'] = self._loaded_fields.as_dict()
if self._include_text_scores: if self._search_text:
if 'fields' not in cursor_args: if 'fields' not in cursor_args:
cursor_args['fields'] = {} cursor_args['fields'] = {}
@ -1608,8 +1593,6 @@ class BaseQuerySet(object):
continue continue
if key == '$text_score': if key == '$text_score':
# automatically set to include text scores
self._include_text_scores = True
key_list.append(('_text_score', {'$meta': "textScore"})) key_list.append(('_text_score', {'$meta': "textScore"}))
continue continue

View File

@ -2785,15 +2785,14 @@ class QuerySetTest(unittest.TestCase):
self.assertTrue('planejamento' in new.title) self.assertTrue('planejamento' in new.title)
query = News.objects.search_text("candidata") query = News.objects.search_text("candidata")
self.assertEqual(query._search_text, "candidata")
self.assertTrue(query._include_text_scores)
new = query.first() new = query.first()
self.assertTrue(isinstance(new.get_text_score(), float)) self.assertTrue(isinstance(new.get_text_score(), float))
# count # count
query = News.objects.search_text('brasil').order_by('$text_score') query = News.objects.search_text('brasil').order_by('$text_score')
self.assertTrue(query._include_text_scores) self.assertEqual(query._search_text, "brasil")
self.assertEqual(query.count(), 3) self.assertEqual(query.count(), 3)
self.assertEqual(query._query, {'$text': {'$search': 'brasil'}}) self.assertEqual(query._query, {'$text': {'$search': 'brasil'}})