将唯一索引字段添加到MongoDB中的集合

将唯一索引字段添加到MongoDB中的集合,mongodb,mongoose,Mongodb,Mongoose,我正在尝试向“用户”集合中的文档添加用户名字段,我希望它是唯一的索引。(到目前为止,我们一直在使用电子邮件地址进行登录,但我们也想添加一个用户名字段。)但是,运行db.users.ensureIndex({username:1},{unique:true})失败,因为mongo认为所有未设置的用户名都是重复的,因此不是唯一的。有人知道怎么避开这个吗 显示当前用户和用户名(如果有): > db.users.find({},{_id:0,display_name:1,username:1})

我正在尝试向“用户”集合中的文档添加用户名字段,我希望它是唯一的索引。(到目前为止,我们一直在使用电子邮件地址进行登录,但我们也想添加一个用户名字段。)但是,运行db.users.ensureIndex({username:1},{unique:true})失败,因为mongo认为所有未设置的用户名都是重复的,因此不是唯一的。有人知道怎么避开这个吗

显示当前用户和用户名(如果有):

> db.users.find({},{_id:0,display_name:1,username:1})
    { "display_name" : "james" }
    { "display_name" : "sammy", "username" : "sammy" }
    { "display_name" : "patrick" }
尝试将“用户名”字段设置为唯一索引:

> db.users.ensureIndex({username:1},{unique:true})
    {
        "err" : "E11000 duplicate key error index: blend-db1.users.$username_1  dup key: { : null }",
        "code" : 11000,
        "n" : 0,
        "connectionId" : 272,
        "ok" : 1
    }
它不起作用,因为
james
sammy
都有
username:null

让我们将
patrick
的用户名设置为“patrick”,以消除重复的
null

> db.users.update({display_name: 'patrick'}, { $set: {username: 'patrick'}});
> db.users.ensureIndex({username:1},{unique:true})
> db.users.getIndexes()
    [
        {
            "v" : 1,
            "key" : {
                "_id" : 1
            },
            "ns" : "blend-db1.users",
            "name" : "_id_"
        },
        {
            "v" : 1,
            "key" : {
                "username" : 1
            },
            "unique" : true,
            "ns" : "blend-db1.users",
            "name" : "username_1"
        }
    ]
现在它工作了

为了澄清这个问题,我希望能够使
username
成为唯一的索引,而不必担心所有
username
仍设置为
null
的文档,尝试创建一个:

根据文件:

您可以将稀疏索引选项与唯一索引选项组合使用 这样mongod将拒绝具有重复值的文档 字段,但忽略没有密钥的文档


虽然这只适用于没有字段的文档,而不是有字段的文档,但是字段有
null
值。

我需要重新检查这一点,但我认为在稀疏索引中,字段不存在和为null是相同的,我记不清了though@Sammaye我可能弄错了,我是基于这一部分的,虽然它已经很老了,事情可能已经发生了变化:)这个答案可能是对的,我只记得关于稀疏的一些事情;值得检查一下它是否不区分大小写?。我认为没有,那么就没有用它来创建唯一的用户名。@RahulTailwal唯一性检查是区分大小写的,因此用户名
foo
foo
被认为是不同的,不会触发唯一性冲突。如果需要区分大小写,可以在将用户名保存到数据库之前使用大写或小写。
> db.users.update({display_name: 'patrick'}, { $set: {username: 'patrick'}});
> db.users.ensureIndex({username:1},{unique:true})
> db.users.getIndexes()
    [
        {
            "v" : 1,
            "key" : {
                "_id" : 1
            },
            "ns" : "blend-db1.users",
            "name" : "_id_"
        },
        {
            "v" : 1,
            "key" : {
                "username" : 1
            },
            "unique" : true,
            "ns" : "blend-db1.users",
            "name" : "username_1"
        }
    ]