在Mongoengine中使用键作为值

1 投票
1 回答
3165 浏览
提问于 2025-04-17 07:23

我在Django中使用mongoengine来操作mongodb。

但是,mongoengine的字段(比如StringField)让我不得不按照我不想要的方式来构建数据结构。我的意思是,它非常严格,要求我在还不知道具体会用什么键名之前,就得先写好键名。例如……

假设我不知道将会把什么键名放入数据库……

> for(var i=0; i<10; i++){
... o = {};
... o[i.toString()] = i + 100;
... db.test.save(o)
... }
> db.test.find()
{ "_id" : ObjectId("4ed623aa45c8729573313811"), "0" : 100 }
{ "_id" : ObjectId("4ed623aa45c8729573313812"), "1" : 101 }
{ "_id" : ObjectId("4ed623aa45c8729573313813"), "2" : 102 }
{ "_id" : ObjectId("4ed623aa45c8729573313814"), "3" : 103 }
{ "_id" : ObjectId("4ed623aa45c8729573313815"), "4" : 104 }
{ "_id" : ObjectId("4ed623aa45c8729573313816"), "5" : 105 }
{ "_id" : ObjectId("4ed623aa45c8729573313817"), "6" : 106 }
{ "_id" : ObjectId("4ed623aa45c8729573313818"), "7" : 107 }
{ "_id" : ObjectId("4ed623aa45c8729573313819"), "8" : 108 }
{ "_id" : ObjectId("4ed623aa45c872957331381a"), "9" : 109 }

[补充]

正如你所看到的,键名之间差别很大……

假设“我事先不知道将会把什么键名放入文档中”。

正如dcrosta回复的那样……我在寻找一种方法,可以在使用mongoengine时不提前指定字段。

[/补充]

我该如何通过mongoengine做到这一点?请给我一个像这样的数据结构设计:

class Test(Document):
    tag = StringField(db_field='xxxx')

[补充]

我不知道'xxxx'会是什么键名。

抱歉……我来自韩国,所以我的英语有点生疏。请分享一些你的知识。谢谢你阅读这篇内容。

[/补充]

1 个回答

2

你有没有考虑直接使用PyMongo,而不是Mongoengine?Mongoengine是用来为你的文档定义和验证结构的,它提供了很多工具和方便的功能。如果你的文档内容会有很大差异,我不太确定Mongoengine是否适合你。

不过,如果你的所有文档都有一些共同的字段,而每个文档又有一些特定的字段,你可以使用Mongoengine的DictField。这样做的缺点是,字段的键不会是“顶层”的,比如:

class UserThings(Document):
    # you can look this document up by username
    username = StringField()

    # you can store whatever you want here
    things = DictField()

dcrosta_things = UserThings(username='dcrosta')
dcrosta_things.things['foo'] = 'bar'
dcrosta_things.things['bad'] = 'quack'
dcrosta_things.save()

这会在MongoDB文档中生成如下内容:

{ _id: ObjectId(...),
  _types: ["UserThings"],
  _cls: "UserThings",
  username: "dcrosta",
  things: {
    foo: "bar",
    baz: "quack"
  }
}

补充:我还想提一下,Mongoengine的开发分支上正在进行“动态”文档的工作,也就是说,当保存模型时,Python文档实例上的属性会被保存。详细信息和历史可以查看https://github.com/hmarr/mongoengine/pull/112

撰写回答