3

如果我尝试添加一些如下所示的 JSON:

{ 'character.treasure_chests': 1 }

Mongoose 会发出这样的错误:

[错误:key character.treasure_chests 不能包含'.']

这是预期的行为吗?

4

4 回答 4

3

我非常有信心,例如:

{"foo.com": 2}

实际上是有效的 JSON。密钥只是一个字符串。

http://jsonlint.com/ 没有抱怨它,我可以在任何我喜欢的地方愉快地使用它,除非我尝试将它分配给 mongoose 模式(以及其他一些地方)中的 Mixed 属性。

你可以在这个小小提琴中看到它的工作原理:http: //jsfiddle.net/gBgB6/1/

有时,我想通过 keypath {"foo.baz":0} 存储一个值,我想将其用作指向 mongo 文档之外的 javascript 对象中的键的指针。我不想将它以嵌套形式存储在 mongo 中,但我也不想像这样重新映射它

{key:"foo.baz",
 value: '0'
} 

我想有几次我可能会通过将点(。)映射到另一个字符来将值存储在表中。

在我看来,猫鼬的缺点。我可能会问它:)。

于 2013-10-13T18:51:40.390 回答
2

这是一个有效的 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 的,但它们不是它的超集。

于 2016-12-24T19:25:20.853 回答
2

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

首先,我将假设这些点不在您的架构中,对吗?换句话说,您将此 JSON 作为您无法控制的Mixed类型的一部分插入。如果你想在你的模式中使用点,那是一个完全不同的故事,我会避免这样做。

但是,为了允许 mongoose 处理混合 JSON 中的点键,您至少可以做两件事:

  1. 替换字符

正如其他人所建议的那样,只需将点替换为另一个字符或字符序列(例如-or )来转义它们-DOT-。当然,这确实意味着,如果您必须映射回原始数据,并且需要将-or替换-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!

当然,为此您需要对数据库进行 2 次调用,从而使插入复杂性有效地加倍,但至少您在 mongodb 中有点键!

请注意,这也可能对您查询这些键的方式产生影响。但是由于这种类型的数据通常是混合类型的,所以无论如何您都不能在那里进行太多的结构化查询。

于 2019-10-21T14:00:31.877 回答
-1

是的。据我所知,有效的 JSON 没有点。你应该做的是:

{
  "character": {
    "treasure_chests": 1
  }
}

这是一个示例:JSON Schema 示例

于 2013-07-05T22:24:46.467 回答