有没有办法在mongoengine中使用更短的`_cls`值?

时间:2013-04-06 08:51:40

标签: optimization database-performance mongoengine diskspace

除了使类的名称更短(这会使代码难以阅读)之外,有没有办法在mongoengine中使用更短的_cls值?

我正在寻找这样的事情:

class User(Document):
    login = StringField(primary_key = True)
    full_name = StringField()
    meta = { "short_class_name": "u" }

class StackOverFlowUser(User):
    rep = IntField()
    meta = { "short_class_name": "s" }

如果存在short_class_name元属性(但我没有找到它或类似的东西),那么我们可以这样:

{ "_cls" : "s", "_id" : "john",
  "full_name" : "John Smith", "rep" : 600 }

而不是:

{ "_cls" : "User.StackOverFlowUser", "_id" : "john",
  "full_name" : "John Smith", "rep" : 600 }

在这个例子中,这可以节省大约20%的空间,在某些情况下,甚至可以更大。

我想mongoengine是开源的,我可以继续编码,但如果你知道一个更简单的解决方案,我很乐意听到它。

感谢。

2 个答案:

答案 0 :(得分:1)

在查看了mongoengine的源代码后,我在大多数情况下 MiniQuark 得到了下一个黑客:

def hack_document_cls_name(cls, new_name):
    cls._class_name = new_name
    from mongoengine.base import _document_registry
    _document_registry[new_name] = cls

或作为类装饰者:

def hack_document_cls_name(new_name):
    def wrapper(cls):
        cls._class_name = new_name
        from mongoengine.base import _document_registry
        _document_registry[new_name] = cls
        return cls
    return wrapper

除了_class_name_document_registry之外,我们没有其他方法。

如果要重命名一个类,必须在类定义之后立即应用此hack(或者至少在定义任何子类之前应用此hack,否则它们将具有基类类长的_types属性名称)。例如:

class User(Document):
    login = StringField(primary_key = True)
    full_name = StringField()

hack_document_cls_name(User, "u")


class StackOverflowUser(User):
    rep = IntField()

hack_document_cls_name(StackOverflowUser, "s")

或作为类装饰者:

@hack_document_cls_name("u")
class User(Document):
    login = StringField(primary_key = True)
    full_name = StringField()


@hack_document_cls_name("s")
class StackOverflowUser(User):
    rep = IntField()

答案 1 :(得分:0)

好的,到目前为止,我能想到的最好的就是这个。它有效,但我确信必须有更少的黑客解决方案......

class U(Document): # User
    meta = { "collection": "user" }
    login = StringField(primary_key = True)
    full_name = StringField()

class S(U): # StackOverflowUser
    rep = IntField()

User = U; del(U)
StackOverflowUser = S; del(S)
User.__name__ = "User"
StackOverflowUser.__name__ = "StackOverflowUser"

现在我这样做了:

StackOverflowUser.objects.create(login="john", full_name="John Smith", rep=600)

我在user集合中获取此文档:

{ "_cls" : "U.S", "_id" : "john", "full_name" : "John Smith", "rep" : 600 }

与标准行为相比,这节省了大约20%的空间。但我不喜欢它是多么的黑暗。