【问题标题】:mongoose compound index for fixed value field固定值字段的猫鼬复合索引
【发布时间】:2016-02-07 18:00:42
【问题描述】:

是否可以制作复合索引,其中一个字段具有固定值?

假设我想避免用户为不同的帐户使用相同的电子邮件,但仅用于普通用户帐户,并且我希望允许管理员在任意数量的地方使用邮件,甚至有一个常规的使用同一电子邮件的用户帐户和管理帐户

User.index({ username: 1, email: 1 }, { unique: true })

没有用,因为它不允许管理员重复使用电子邮件。有没有可能做类似的事情?

User.index({ role: "regular_user", username 1, email: 1}, { unique: true });

【问题讨论】:

  • 我发布了一个关于索引的答案,这可以帮助您确定创建复合索引是否适合您,其中一个字段具有固定值。 stackoverflow.com/questions/33545339/…
  • 好答案。实际上,就我而言,我正在改进 mongoose (github.com/briankircho/mongoose-schema-extend) 的模式继承包装器,并且我必须将所有唯一键更改为鉴别器/键唯一索引,但仅限于那些定义此类字段的鉴别器值作为独一无二的。上面的例子是我能找到的最容易解释的例子。
  • 你的结果如何?
  • 根据您的回答,我有一个想法。明天我会通知你(并接受你的回答)
  • 我接受了您的回答,因为它对我提出的问题很有用,并且可能对其他人有用。无论如何,我仍然坚持这一点:-p

标签: mongodb mongoose


【解决方案1】:

路易斯,

关于您给出的示例。如果您创建唯一复合索引,则各个键可以具有相同的值,但索引条目中存在的跨键的值组合只能出现一次。因此,如果我们在 {"username" : 1, "role" : 1} 上有一个唯一索引。以下插入是合法的:

> db.users.insert({"username" : "Luis Sieira"})
> db.users.insert({"username" : "Luis Sieira", "role" : "regular"})
> db.users.insert({"username" : "Luis Sieira", "role" : "admin"})

如果您尝试插入上述任何文档的第二个副本,则会导致重复键异常。

您的场景

我认为,如果您在架构中添加了 allowance 字段。当您为新帐户的管理员插入时。您可以为他们的管理员津贴添加不同的值。如果您为 {"username":1,"email":1, "allowance" : 1} 添加了唯一索引

您可以合法地进行以下插入:

>db.users.insert({"username" : "inspired","email": "i@so.com", "allowance": 0})
>db.users.insert({"username" : "inspired","email": "i@so.com", "allowance": 1})
>db.users.insert({"username" : "inspired","email": "i@so.com", "allowance": 2})
>db.users.insert({"username" : "inspired","email": "i@so.com", "allowance": 3})

当然,您必须处理来自客户端的某些逻辑,但这将允许您对regular 帐户使用0 的许可代码,然后允许您保存更高的许可代码(递增它或为其添加自定义值)每次admin 创建另一个帐户时。

我希望这能为使用独特的复合索引提供一些方向。

【讨论】:

    【解决方案2】:

    你在正确的轨道上。首先,如果您像这样使用role 定义索引

    User.index({role: 1, username: 1, email: 1}, { unique: true });
    

    Mongo 将对未指定 role 字段的文档使用 null。如果插入用户时未指定role,然后再次尝试添加,则会出现错误,因为这三个字段已经存在于数据库中。因此,您可以通过不包含角色来利用这一点(或者您可以使用预定义的值来更好地阅读,就像您建议的 regular_user)。

    现在,棘手的部分是强制索引允许管理员bypass 唯一性约束。最好的解决方案是生成一些哈希并将其添加到角色中。因此,如果您只是添加具有admin_user 等角色的管理员,您将不会绕过约束。同时,使用像admin_user_635646 这样的角色(总是有不同的后缀)将允许您多次插入同一个管理员。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-25
      • 2020-02-17
      • 1970-01-01
      • 2017-03-02
      • 1970-01-01
      • 1970-01-01
      • 2021-04-17
      • 2017-01-26
      相关资源
      最近更新 更多