在MongoDB中使用动态密钥字段的JSON模式

fin*_*fin 14 jsonschema mongodb

想要对存储在mongodb集合中的对象提供i18n支持

目前我们的架构如下:

{
  _id: "id"
  name: "name"
  localization: [{
    lan: "en-US",
    name: "name_in_english"
  }, {
    lan: "zh-TW",
    name: "name_in_traditional_chinese"
  }]
}
Run Code Online (Sandbox Code Playgroud)

但我的想法是字段"lan"是唯一的,我可以只使用此字段作为键,因此结构将是

{
  _id: "id"
  name: "name"
  localization: {
    "en-US": "name_in_english",
    "zh-TW": "name_in_traditional_chinese"
  }
}
Run Code Online (Sandbox Code Playgroud)

这将更整洁,更容易解析(只是本地化[语言]将获得我想要的特定语言的价值).

但问题是:在MongoDB中存储数据这是一个很好的做法吗?以及如何通过json-schema检查?

Der*_*ick 6

将值作为键是不好的做法.语言代码是值,正如您所说,您无法根据模式验证它们.它使查询不可能.例如,您无法弄清楚您是否 "nl-NL"的语言翻译,因为您无法与键进行比较,也无法轻松地将其编入索引.你应该总是有描述性的键.

但是,正如您所说,将语言作为键使得将数据拉出更容易,因为您可以通过它['nl-NL'](或任何语言的语法)来访问它.

我会建议一个替代架构:

{
    your_id: "id_for_name"
    lan: "en-US",
    name: "name_in_english"
}
{
    your_id: "id_for_name"
    lan: "zh-TW",
    name: "name_in_traditional_chinese"
}
Run Code Online (Sandbox Code Playgroud)

现在你可以 :

  • { your_id: 1, lan: 1 }为快速查找设置索引
  • 单独查询每个翻译并获得该翻译:
    db.so.find( { your_id: "id_for_name", lan: 'en-US' } )
  • 使用相同的索引查询每个id的所有版本:
    db.so.find( { your_id: "id_for_name" } )
  • 并且更容易更新特定语言的翻译:

    db.so.update(
        { your_id: "id_for_name", lan: 'en-US' }, 
        { $set: { name: "ooga" } } 
    )
    
    Run Code Online (Sandbox Code Playgroud)

使用您建议的模式,这些点都不可能.

  • 废话."查询翻译单独":`db.so.find({ 'localization.lan': 'EN-US'})`(指数将在这里帮助),或`db.so.find({'localization.en -US':{$ exists:true}})`."查询每个id的所有翻译":`db.so.find({_ id:'id'})`.如果只需要翻译,请添加字段说明符."更新特定翻译":`db.so.update({_ ID: '身份证', 'localization.lan': 'EN-US'},{$设置:{ '$本地化名称': 'OOGA' }})`或`db.so.update({_ ID: '身份证', 'localization.en美':{$存在:真}},{$设置:{ 'localization.en-US.name': 'OOGA'}})`.每种方法都有独特的特点; 没有一个是"坏习惯". (7认同)
  • 这是一个糟糕的建议 (3认同)