Mongoose.js getter 在 Find() 上膨胀子文档?

Posted

技术标签:

【中文标题】Mongoose.js getter 在 Find() 上膨胀子文档?【英文标题】:Mongoose.js getter that inflates subdocuments on Find()? 【发布时间】:2015-03-26 22:16:54 【问题描述】:

是否存在与 Mongoose.js 验证相反的情况,可以在检索父文档时膨胀子文档?我可能已经看文档太久了,我不知道现有的功能是什么。

MongoDB 的一个优点是查询规范(例如 likes: $gt: 10, $le: 14 本身就是 javascript 对象,并且直到最近才将它们作为子文档存储在 MongoDB 实例中。

但是,从 MongoDB 2.4 升级到 2.6,这些存储不再有效,现在出现错误:The dollar ($) prefixed field '$or' ... is not valid for storage

因此处于Google Groups Discussion 的情况。那里的作者建议将文档展平为字符串。如果子文档具有嵌入点的合法 Javascript 属性(例如"802.11g": ...),也会发生这种情况

通过在 Mongoose.js 中指定 JSON.parseJSON.stringify 作为 getter/setter 很容易:

var ProjectSchema = new Schema(   
  name:  type: String, required: false, default: "New project" ,
  spec: type: mongoose.Schema.Types.Mixed, set: JSON.stringify, get: JSON.parse,
);

但只有当我明确要求属性值时才会调用 getter。该属性仍然是下面的字符串,并按如下方式传递:

Project.findById(req.params.projectId, function(err, project) 
  console.log("......"+(typeof project.spec))  // project.spec is an object!
  res.send(project); // project.spec is a String!
);

显然,我可以在每个Model.find(...) 调用中调用model.spec = JSON.parse(model.spec),并为每个扁平属性调用,但最好在一个中心位置进行。

https://groups.google.com/forum/?fromgroups=#!topic/mongoose-orm/8AV6aoJzdiQ

【问题讨论】:

所以您想将数据结构作为字符串存储在文档数据库中,但无论如何都支持仅存储数据结构?如果您看不出这里有什么令人难以置信的错误,我不确定我是否真的可以帮助您。 @NeilLunn,看起来 OP 要保存的数据结构的一部分使用了带有美元前缀的键,因此不能直接存储。 你试过猫鼬的虚拟机了吗? mongoosejs.com/docs/api.html#schema_Schema-virtual 既然你们都在看。您不打算查询我收集的数据,因此替换东西真的无关紧要,或者您可以通过相同的规则集过滤查询构建。但只需用合法的替代品替换保留字符。至于 MongoDB 的功能,$ 是为操作员(以及您要存储的内容)以及 . 保留的,它位于点表示法中。所以我个人会用另一层替换保留字符(猫鼬并不是真的要独立)所以至少我有能力查询我是否愿意。 @user645715 您应该能够通过在ProjectSchema 定义中添加toJSON: getters: true 选项来调用res.send 中的getter。你试过吗? toObject 你可能也想要它。 【参考方案1】:

您可以通过将toJSON: getters: true 选项添加到ProjectSchema 定义来调用res.send 中的getter。您可能希望为 toObject 选项启用它,以及将文档传递给 console.log 等情况。

var ProjectSchema = new Schema(   
  name:  type: String, required: false, default: "New project" ,
  spec: type: mongoose.Schema.Types.Mixed, set: JSON.stringify, get: JSON.parse,
, 
  toJSON: getters: true,
  toObject: getters: true
);

文档here.

【讨论】:

@NeilLunn 同意保持可搜索是值得的,所以选择set: foo, get: unfoo 其中function foo(val) return JSON.stringify(val).replace(/\"\$/,'\"_$'); function unfoo(val) return JSON.parse(val.replace(/\"_\$/,'\"$'));

以上是关于Mongoose.js getter 在 Find() 上膨胀子文档?的主要内容,如果未能解决你的问题,请参考以下文章

Could not find a getter for orderItems in class

错误:Could not find a getter for CreatTime in class

我如何在猫鼬上使用“LIKE”运算符?

org.hibernate.PropertyNotFoundException: Could not find a getter for employee in class com.itcast.f_

Mongoosejs - 我可以在“查找”的后查询中间件中修改文档吗?

Node.js:如何在 mongoose.js 中执行 count 命令?