【问题标题】:Mongoose.js getter that inflates subdocuments on Find()?Mongoose.js getter 在 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 你可能也想要它。

标签: json node.js mongodb mongoose getter-setter


【解决方案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(/\"_\$/,'\"$')); }
猜你喜欢
  • 2018-03-25
  • 2016-09-29
  • 2016-06-07
  • 1970-01-01
  • 1970-01-01
  • 2019-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多