【发布时间】:2013-07-04 02:06:10
【问题描述】:
在我的 Mongoose 模式中,我有一个字符串字段,我希望能够在其中存储一个 JSON 对象。可能吗?在 Postgres 中,可以将字典存储在字符串列中。
我想这样做是因为字典(实际上是 JS 中的 JSON 对象)只是一个简单的读写值,不需要查询,而且因为它只是一个值而不是值数组。
【问题讨论】:
在我的 Mongoose 模式中,我有一个字符串字段,我希望能够在其中存储一个 JSON 对象。可能吗?在 Postgres 中,可以将字典存储在字符串列中。
我想这样做是因为字典(实际上是 JS 中的 JSON 对象)只是一个简单的读写值,不需要查询,而且因为它只是一个值而不是值数组。
【问题讨论】:
是的,您可以只存储{myJsonProperty: JSON.stringify(myObject)}。希望您知道您也可以在您的猫鼬模式中设置{myJsonProperty: Object} 并存储整个对象,而无需无缘无故地将其转换为字符串。它不必是带有架构的嵌套文档,它可以只是一个普通的 javascript 对象。
【讨论】:
Mixed 类型。 github.com/LearnBoost/mongoose/blob/3.6.14/lib/schema/mixed.js
如果您可以将字段形式“String”的类型更改为“Object”,则可以按原样保存 json。
var schema_obj = new Schema({
field1: Object,
..
});
【讨论】:
接受的答案适用于大多数情况。
但是,如果您有一个要存储的对象,并且您无法控制对象键(例如,它们可能是用户提交的),您可能需要考虑将它们存储为字符串化 JSON。这使您可以克服 MongoDB 施加的 keys must not contain the reserved characters $ 或 . 的限制。
您可以使用 Mongoose 的 getter 和 setter 来实现这一点,例如:
data: {
type: String,
get: function(data) {
try {
return JSON.parse(data);
} catch(error) {
return data;
}
},
set: function(data) {
return JSON.stringify(data);
}
}
【讨论】:
由于堆栈溢出的 6 次更改限制,无法更改原始文件。重新发布,很棒的工作 Tom,只是在 catch 块中丢失了 catch(err)
data: {
type: String,
get: function(data) {
try {
return JSON.parse(data);
} catch(err) {
return data;
}
},
set: function(data) {
return JSON.stringify(data);
}
}
【讨论】:
我们需要保留结构而不是字符串,所以我想出了以下方法来处理这个问题:
const setMongoMixedWithBadKeys = data =>
Array.isArray(data)
? data.map(setMongoMixedWithBadKeys)
: typeof data === 'object'
? Object.entries(data).reduce((a, [key,value])=>({...a, [key.replace('.','__').replace('$','___')]:setMongoMixedWithBadKeys(value)}), {})
: data
const getMongoMixedWithBadKeys = data =>
Array.isArray(data)
? data.map(getMongoMixedWithBadKeys)
: typeof data === 'object'
? Object.entries(data).reduce((a, [key, value])=> ({...a, [key.replace('__','.').replace('___','$')]:getMongoMixedWithBadKeys(value)}), {})
: data
data: {
type: Mixed,
get: getMongoMixedWithBadKeys,
set: setMongoMixedWithBadKeys
}
【讨论】: