我即将建立我的 node .js/express/mongoose/passport应用程序,我正在考虑用户和帐户的正确schema design.

There will be users loging in from twitter and facebook as well as from native accounts. At a later stage I want a user to connect both twitter and facebook with my application (and maybe even more external accounts).

我想不出解决那种情况的好办法.以下是我正在考虑的选项:

1.拥有个人资料模型和账户模型.配置文件文档代表唯一的用户,而帐户提供用户名和密码(内部帐户)或来自身份验证提供程序(外部帐户)的身份验证数据.配置文件必须至少有一个nested帐户文档.

var ExtAccountSchema = new Schema({
    type: String, // eg. twitter, facebook, native
    uid: String
});

var IntAccountSchema = new Schema({
    username: String,
    password: String
});

var ProfileSchema = new Schema({
    firstname: String,
    lastname: String,
    email: String,
    accounts: [Account] // Pushing all the accounts in there
});

我不喜欢的是,不同的帐户数据导致的帐户文档不太一致,而且当我的用户登录时,我很难找到正确的帐户(在嵌套文档中搜索UID和帐户类型)

2.所有数据都在a single model

var ProfileSchema = new Schema({
    firstname: String,
    lastname: String,
    email: String,        
    twitter-uid: String,
    facebook-uid: String
    password: String
});

这太难看了找到正确的帐户数据可能更容易/更快,但维护起来并不好.

有更好的解决方案吗?Is there a best practice?

推荐答案

1) 在MongoDB中构建数据时,您可能会采取三种策略:

  • a) 嵌入文档数组
  • b) 嵌入引用数组
  • c) 扩展到父文档中

策略(a)是您描述的第一个策略,其中概要文件包含一系列帐户子文档.

策略(b)与策略(a)类似,但您会使用对其他文档(通常在帐户集合中)的一系列引用,而不是嵌入实际文档.

策略(c)是您描述为"将所有数据放在一个模型中"的策略.

2) 通常认为使用一系列嵌入式文档是最佳实践,尤其是当其中的信息可能会发生变化时.如果这能让你的生活更轻松,你可以使用一个键来区分账户的类型,比如:

  { 
    firstname: 'Fred',
    lastname: 'Rogers',
    email: 'fred.rogers@example.com',

    accounts: [
             { kind: 'facebook',
               uid: 'fred.rogers'
             },
             { kind: 'internal',
               username: 'frogers',
               password: '5d41402abc4b2a76b9719d911017c592'
             },
             { kind: 'twitter',
               uid: 'fredr'
             }
          ]
    }

3) MongoDB允许您搜索嵌入的文档.因此,您将编写以下查询(JavaScript语法):

 db.profile.find( 
        { email: 'fred.rogers@example.com', 'accounts.kind': 'facebook' }
        );

有了适当的索引,这个查询会非常快.

Mongodb相关问答推荐

如何从文档列表的数组内部打印一个对象?

在提供的文档(_Id)之后和之前,是否有一个Mongo操作来获取已排序(和/或过滤)集合中的文档计数?

将子元素的数组值提取到 mongodb 中的单个数组中?

MongoDB 聚合 - $project 和 $match 阶段未按预期工作

按数组mongodb中的第一个元素排序

Mongodb Timeseries / Golang - ['timestamp' 必须存在并包含有效的 BSON UTC 日期时间值]

MongoDB:通过嵌套数组中的最后一个元素值获取文档

有没有办法从另一条记录中插入一条记录

使用模拟 MongoDB 服务器进行单元测试

在 Heroku 上使用 Node 读取、写入和存储 JSON

用 BsonRepresentation(BsonType.ObjectId) vs BsonId vs ObjectId 在 C# 中装饰属性之间的区别

如何更新 mongodb 文档以向数组添加新元素?

MongoDB - 清除嵌套数组中的元素

在 MongoDB 中按条件分组

如何使用node.js http服务器从mongodb返回大量行?

Mongo聚合框架,排序然后分组不起作用

Flask:设置应用程序和请求特定的属性?

MongoDB 中的多个 $inc 更新

在 MongoDB 中比较日期(moment.js)

Spring Data MongoDB - 在哪里以编程方式为 Mongo 集合创建索引?