唯一索引确保索引字段不存储重复值;即强制索引字段的唯一性。默认情况下,MongoDB在创建集合时在id字段上创建一个唯一的索引。
从Mongodb4.2版本开始,功能兼容性版本为4.2(或更高),MongoDB为唯一索引使用了一种新的内部格式,这与早期的MongoDB版本不兼容,新格式适用于现有的唯一索引以及新创建/重建的唯一索引。
1、在更新mongodb文档字段时出现了索引为空值的提示
db.version()
4.2.18
db.test2.update({"cr_user":"0d69c51de9ea464da4b3aff397fa3d0a"}, {"us_amount": NumberLong(104857600)});
WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: jia_test.test2 index: cr_user_1 dup key: { cre_user: null }"
}
})
1.2、查看集合索引:
> db.test2.getIndexes() //查看集合索引
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "jia_test.test2"
},
{
"v" : 2,
"unique" : true, //唯一索引
"key" : {
"cr_user" : 1
},
"name" : "cr_user_1",
"ns" : "jia_test.test2"
}
]
1.3、看了官方文档是这么说的: 感兴趣的可以点击文字查看官方文档
++如果一个文档在唯一索引中没有索引字段的值,那么该索引将为这个文档存储一个空值。由于唯一约束,MongoDB只允许一个缺少索引字段的文档。如果有多个文档没有索引字段的值或缺少索引字段,那么索引构建将会由于重复键错误而失败.++
操作:删除掉没有唯一索引字段的文档,更新成功。
> db.test2.remove({"us_amount" : NumberLong(104857600)})
WriteResult({ "nRemoved" : 1 })
> db.test2.update({"cr_user":"0d69c51de9ea464da4b3aff397fa3d0a"}, {"us_amount": NumberLong(104857600)});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
2、唯一索引:
可以在单一字段创建,创建唯一索引命令 db.collection.createIndex() 将unique 设置为true
db.collection.createIndex( <key and index type specification>, { unique: true } )
db.members.createIndex( { "user_id": 1 }, { unique: true } ) //user_id字段创建唯一索引
{
"createdCollectionAutomatically" : true,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
插入一条数据
db.members.insert({"user_id":1,"name":"zhangsan"})
WriteResult({ "nInserted" : 1 })
唯一字段重复插入
db.members.insert({"user_id":1,"name":"lisi"})
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: jia_test.members index: user_id_1 dup key: { user_id: 1.0 }"
}
})
插入不包含唯一索引字段的数据
db.members.insert({"name":"lisi"})
WriteResult({ "nInserted" : 1 }) //插入第二条不成功
db.members.insert({"name":"wangwu"})
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: jia_test.members index: user_id_1 dup key: { user_id: null }"
}
})
也可以创建复合唯一索引
db.members.createIndex( { groupNumber: 1, lastname: 1, firstname: 1 }, { unique: true } )
{
"createdCollectionAutomatically" : true,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
另一个例子是,考虑一个具有以下文档的集合
{ _id: 1, a: [ { loc: "A", qty: 5 }, { qty: 10 } ] }
db.collection.createIndex( { "a.loc": 1, "a.qty": 1 }, { unique: true } )
唯一索引允许将以下文档插入到集合中,
db.collection.insertMany( [
{ _id: 2, a: [ { loc: "A" }, { qty: 5 } ] },
{ _id: 3, a: [ { loc: "A", qty: 10 } ] }
] )
因为该索引对a.loc和a.qty值的组合强制唯一性,所以下列数据插入是成功的
> db.collection.createIndex( { "a.loc": 1, "a.qty": 1 }, { unique: true } )
{
"createdCollectionAutomatically" : true,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.collection.insertMany( [
{ _id: 2, a: [ { loc: "A" }, { qty: 5 } ] },
{ _id: 3, a: [ { loc: "A", qty: 10 } ] }
] )
{ "acknowledged" : true, "insertedIds" : [ 2, 3 ] }
> db.collection.insertMany( [
{ _id: 4, a: [ { loc: "C" }, { qty: 10 } ] },
{ _id: 5, a: [ { loc: "D", qty: 10 } ] } ] )
{ "acknowledged" : true, "insertedIds" : [ 4, 5 ] }