Optimization 有没有办法在mongoengine中使用更短的“\u cls”值?

Optimization 有没有办法在mongoengine中使用更短的“\u cls”值?,optimization,database-performance,mongoengine,diskspace,Optimization,Database Performance,Mongoengine,Diskspace,除了缩短类的名称(这会使代码难以阅读)之外,是否还有其他方法可以在mongoengine中使用更短的\u cls值 我在找这样的东西: class User(Document): login = StringField(primary_key = True) full_name = StringField() meta = { "short_class_name": "u" } class StackOverFlowUser(User): rep = IntFi

除了缩短类的名称(这会使代码难以阅读)之外,是否还有其他方法可以在mongoengine中使用更短的
\u 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\u class\u name
meta属性(但我没有找到它或任何类似的属性),那么我们可以这样做:

{ "_cls" : "s", "_id" : "john",
  "full_name" : "John Smith", "rep" : 600 }
与此相反:

{ "_cls" : "User.StackOverFlowUser", "_id" : "john",
  "full_name" : "John Smith", "rep" : 600 }
在本例中,这将节省大约20%的空间,在某些情况下,节省的空间可能更大

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


谢谢。

好的,到目前为止,我能想到的最好的办法就是这个。这是可行的,但我相信一定会有不那么粗俗的解决方案

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)
我在
用户
集合中获得此文档:

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

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

在查看了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
@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()
除了使用
\u class\u name
\u document\u注册表
进行黑客攻击之外,我们看不到其他方法

当您想要重命名一个类时,您必须在类定义之后立即应用此hack(或者至少在您定义任何子类之前,否则它们将具有带有基类长名称的
\u 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")
或作为类装饰器:

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
@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()

创建工作(
StackOverFlowUser.objects.create(login=“john”,full\u name=“john Smith”,rep=600)
),但不幸的是,查找不工作(
User.objects.get(login=“john”)
引发异常
未注册:'s'未在文档注册表中注册
。查看mongoengine源代码,
DocumentMetaclass
在创建文档类时执行以下代码:
\u document\u registry[新建\u类。\u类\u名称]=新建\u类
\u document\u注册表
稍后在文档查找期间使用。因此,在创建类后更改
\u class\u名称
可能太晚了(或者我们需要破解\u document\u注册表)。噢,抱歉,我没有检查此项。您的解决方案看起来很有效。但是这是黑客攻击。您可以修复您的答案以匹配我的答案,以便我可以更新它吗?我感谢您的帮助,但我不能像现在这样更新您的答案。我将在以后删除我的答案。我用您的答案更新了我的答案,并添加了看起来有点像类装饰器的示例对我来说很漂亮。