Mongodb 是否可以使用MongoEngine删除字段,而不使用strict=False?

Mongodb 是否可以使用MongoEngine删除字段,而不使用strict=False?,mongodb,mongoengine,Mongodb,Mongoengine,我在MongoDB中有很多数据,我们主要通过MongoEngine访问这些数据,有时数据首先出现在字段F1中,然后我们决定字段F2是更好的位置,所以我们将其移到了那里,并停止使用F1 这很方便,但现在我们在旧的F1键中有一堆过时(或无用)的数据,并且毫无理由地使用空的F1键创建新文档 虽然MongoDB是无模式的很方便,但我仍然欣赏strict=True特性(默认情况下是打开的),并尽量避免在绝对必要时关闭它。我不喜欢关掉所有的安全检查 那么,有没有办法从我的MongoDB集合中删除字段F1,而

我在MongoDB中有很多数据,我们主要通过MongoEngine访问这些数据,有时数据首先出现在字段F1中,然后我们决定字段F2是更好的位置,所以我们将其移到了那里,并停止使用F1

这很方便,但现在我们在旧的F1键中有一堆过时(或无用)的数据,并且毫无理由地使用空的F1键创建新文档

虽然MongoDB是无模式的很方便,但我仍然欣赏
strict=True
特性(默认情况下是打开的),并尽量避免在绝对必要时关闭它。我不喜欢关掉所有的安全检查

那么,有没有办法从我的MongoDB集合中删除字段F1,而不需要停机,也不需要
strict=False

  • 如果我首先从文档子类中删除该字段,MongoEngine在尝试加载现有文档时会抱怨

  • 如果首先从数据库中删除该字段,MongoEngine将为任何新记录创建该字段,直到模型更新

MongoEngine有没有办法说“这是一个旧字段。如果有,您可以加载(或忽略)它,但不要为任何新文档创建它”

如果首先从数据库中删除该字段,MongoEngine将为任何新记录创建该字段,直到模型更新


仅当显式写入该字段或该字段设置了默认值时,才为真。否则,该字段将不存在于MongoDB中

因此,作为第一步,我建议删除写入该字段的代码并删除默认值(或将其设置为无)。然后从数据库中删除该字段是安全的

下面是一个小证明:

import mongoengine

class Foo(mongoengine.Document):
    a = mongoengine.IntField()
    b = mongoengine.ListField(default=None)

f = Foo().save()
type(f.a)  # NoneType
type(f.b)  # NoneType
和数据库查询:

> db.foo.findOne()
{ "_id" : ObjectId("56c49ae8ee8b341b4ea02fcb") }

所以你基本上是在问。“拥有不严格符合我们严格模式的数据可以吗?”。MongoDB本身是无模式的,设计时并不在意。一旦你开始使用一个真正关心的软件层,那么你就必须遵守这些规则。因此,您在这里的选择似乎是A。使模式规则不关心不一致的数据。B.更改数据以适应模式规则。这是一个非常好的二进制解决方案集。因此,如果您想进行更改,那么可以使用“原始”方法来进行操作,而不要求它符合模式。所有模式对象都有一个
.collection
访问器,它提供从核心驱动程序访问底层集合对象和方法的权限。首先,我的问题是关于MongoEngine,而不是MongoDB。显然,如果我把模式完全扔出窗口,那么这很容易。这是毫无疑问的。其次,你关于使用“原始”方法的建议听起来像是我第二个要点的一个具体变体。谢谢你的帮助,但我知道怎么做。问题在于(取决于配置和顺序),要么MongoEngine拒绝加载这些记录,要么将过时的字段添加到它创建的任何新文档中,这违背了整个目的。我正在寻找如何实现第三种解决方案,“告诉模式放松对这一字段的限制”。例如,我使用过的每个RDBMS ORM都有这种能力。期望它成为文档对象映射器并不过分。那么你还没有回答你自己的问题吗?如果要存储不符合架构的数据,则设置允许严格处理为false。正如我所说(以及我所说的),这是一个选择,要么不严格,要么改变底层存储。因此,我真的看不出问题本身有什么意义,因此我试图提示您进行一些澄清,而不是一个论点。“只有当您显式写入该字段或该字段设置了默认值时,这才是正确的。”根据经验,这不是我的计算机上发生的情况。您使用的是哪个版本的MongoEngine?我使用的是
MongoEngine==0.10.0
,也使用
MongoEngine==0.10.6
进行了测试,结果相同