如果我尝试添加一些看起来像这样的JSON:
{ 'character.treasure_chests': 1 }
猫鼬吠声有这样的错误:
[错误:关键字符.treasure_chests不得包含'。']
这是预期的行为吗?
答案 0 :(得分:3)
我非常有信心:
{"foo.com": 2}
实际上是有效的JSON。关键只是一个字符串。
http://jsonlint.com/并没有抱怨它,我可以随心所欲地使用它,除非我尝试将它分配给mongoose模式(以及其他一些地方)的混合属性。
你可以看到它在这个小提琴中起作用:http://jsfiddle.net/gBgB6/1/
有时候,我想通过一个keypath {“foo.baz”:0}存储一个值,我想用它作为指向mongo文档之外的javascript对象中的键的指针。我不想在mongo中以嵌套的形式存储它,但我也不想重新映射它像
{key:"foo.baz",
value: '0'
}
我想有几次我可能会通过将点(。)映射到另一个字符来使用在表中存储值。
在我看来猫鼬很短暂。我可能会问:)。
答案 1 :(得分:1)
它是一个有效的JSON,但是无效的Mongoose Schema。自从Mongoose'方法允许路径导航,如果您有类似
的东西{
'some.path': 'foo',
'some': {
'path': 'bar'
}
}
如果不是为了这个"缺点",像document.get('some.path')
这样的方法不知道该怎么做。
这并不意味着你不能使用猫鼬的点。您可以将JSON指定为值:
Schema = new mongoose.Schema({
'some': {
'path': {
'json': {} //any js object
}
}
})
Model = mongoose.model(Schema)
document = new Model()
document.some.path.json = {'inner.data': 'foo'}
Yo可以通过普通document.some.path.json['inner.data']
访问数据,但由于此架构路径1}},您无法使用document.get()
以及'some.path.json'
以外的路径参数来自Mongoose'视角是终点。您对查询此类字段的方式也将受到限制
总而言之,mongoose文档都基于JSON,但它们不是它的超集。
答案 2 :(得分:1)
我也遇到了这个问题,当从您几乎无法控制的源中加载数据时,我也将其视为PITA。有一些解决方法,请参见下文。
首先,我将假定这些点不在您的架构中,对吗?换句话说,您要将此JSON插入为Mixed类型的一部分,而您无法对其进行控制。如果您想在架构中使用点,那就完全不一样了,我会避免这样做。
尽管要允许猫鼬处理混合JSON中的虚线键,您至少可以做两件事:
正如其他人所建议的那样,只需将点替换为其他字符或字符序列(例如-
或-DOT-
)即可。当然,这确实意味着,如果您必须映射回原始数据,并且需要用常规的-
代替-DOT-
或.
,那一定要确保原来那里没有-
或-DOT-
的地方也将被替换...
此外,它还在数据库层的前面添加了一个预处理步骤,在可能的情况下,我会尽量避免这样做。
我实际上已经注意到猫鼬只会在创建新对象时抱怨这一点,例如:
let foo = new Foo({ data: {'character.treasure_chests': 1 }});
foo.save(); // results in Error: key character.treasure_chests must not contain '.'
但是,当您更新现有文档时,它似乎并没有抱怨点:
let foo = new Foo({ data: {}});
await foo.save(); // first save the new object
foo.data = {'character.treasure_chests': 1 };
foo.save(); // no errors when updating the existing object!
当然,您需要为此进行两次数据库调用,这实际上使插入复杂度增加了一倍,但至少在mongodb中具有虚线键!
请注意,这也可能影响您查询这些键的方式。但是,由于这种类型的数据通常是混合类型的,因此无论如何您都无法在其中进行太多的结构化查询。
答案 3 :(得分:-1)
是的,确实如此。据我所知,有效的JSON没有点。 你应该做的是:
{
"character": {
"treasure_chests": 1
}
}
以下是一个示例:JSON Schema example