无法将带有点(键路径)的键添加到类型为:Schema.Types.Mixed的Mongoose字段中

时间:2013-07-02 03:49:46

标签: json mongoose

如果我尝试添加一些看起来像这样的JSON:

{ 'character.treasure_chests': 1 }

猫鼬吠声有这样的错误:

  

[错误:关键字符.treasure_chests不得包含'。']

这是预期的行为吗?

4 个答案:

答案 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']访问数据,但由于此架构路径document.get()以及'some.path.json'以外的路径参数来自Mongoose'视角是终点。您对查询此类字段的方式也将受到限制

总而言之,mongoose文档都基于JSON,但它们不是它的超集。

答案 2 :(得分:1)

我也遇到了这个问题,当从您几乎无法控制的源中加载数据时,我也将其视为PITA。有一些解决方法,请参见下文。

首先,我将假定这些点不在您的架构中,对吗?换句话说,您要将此JSON插入为Mixed类型的一部分,而您无法对其进行控制。如果您想在架构中使用点,那就完全不一样了,我会避免这样做。

尽管要允许猫鼬处理混合JSON中的虚线键,您至少可以做两件事:

  1. 替换字符

正如其他人所建议的那样,只需将点替换为其他字符或字符序列(例如--DOT-)即可。当然,这确实意味着,如果您必须映射回原始数据,并且需要用常规的-代替-DOT-.,那一定要确保原来那里没有--DOT-的地方也将被替换... 此外,它还在数据库层的前面添加了一个预处理步骤,在可能的情况下,我会尽量避免这样做。

  1. 使用更新而不是新的

我实际上已经注意到猫鼬只会在创建新对象时抱怨这一点,例如:

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