我想创建一个索引,以确保在a serialNr
+ manufacturer
的组合中没有重复的art
。但是有些项目没有serialNr
。这些我不想检查/索引。
码mySchema.index({ serialNr: 1, art: 1 , manufacturer: 1, deleted: 1}, { unique: true, sparse: true)
我还尝试了添加部分过滤器:partialFilterExpression: { serialNr: {$ne:null} }
到索引选项。
题
我如何索引它插入:[{art: 'a', manufacturer:'a', deleted:null}, {art: 'a', manufacturer:'a', deleted:null}]
通过
和[{serialNr: '123', art: 'a', manufacturer:'a', deleted:null}, {serialNr: '123', art: 'a', manufacturer:'a', deleted:null}]
失败
我不是要保存:[{serialNr: null, art: 'a', manufacturer:'a', deleted:null}, {serialNr: null, art: 'a', manufacturer:'a', deleted:null}]
mongo docs声明,如果复合索引中缺少字段,则不应为其建立索引:
稀疏索引仅基于
索引字段的存在,或者对于复合索引,是否存在
索引字段。
https://docs.mongodb.org/manual/core/index-partial/
编辑:
新指数implantSchema.index({ serialNr: 1, art: 1 , manufacturer: 1, deleted: 1}, { unique: true, partialFilterExpression: { serialNr: {$exists:true} }})
在对索引进行更改之前,请将collection
放到dev数据库中,以确保不存在旧索引。这是在db.items.getIndexes()
上返回的新索引/* 0 */{ "0" : { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "LOC_db.items" }, "1" : { "v" : 1, "unique" : true, "key" : { "serialNr" : 1, "art" : 1, "manufacturer" : 1, "deleted" : 1 }, "name" : "serialNr_1_art_1_manufacturer_1_deleted_1", "ns" : "LOC_db.items", "partialFilterExpression" : { "serialNr" : { "$exists" : true } }, "background" : true }}
数据
我有一个预保存钩子,可以在其中检查serialNr
的值,该值在返回dup error
之前不存在。
查询数据库时,不存在具有doc
,null
作为""
值的serialNr
。
查询db.items.find({ serialNr: {$exists:true} })
与任何项目都不匹配。
错误insertDocument :: caused by :: 11000 E11000 duplicate key error index: LOC_db.items.$serialNr_1_art_1_manufacturer_1_deleted_1 dup key: { : null, : "Robo", : "Olymp", : null }
附加信息
该错误可能与以下方面有关:
https://github.com/Automattic/mongoose/issues/2457
最佳答案
您实际上已经很接近解决方案,创建索引时只需使用此方法:
partialFilterExpression: { serialNr: {$exists:true} }
确保至少具有3.2版本的mongo
范例:
db.col.createIndex({a:1, b:1},{unique:true, partialFilterExpression: { a: {$exists:true} })
db.col.save({a:50, b:27}) //pass
db.col.save({a:50, b:27}) //fails
db.col.save({b:27}) //pass
db.col.save({b:27}) //pass
db.col.save({b:27}) //pass
db.col.save({a:50, b:27}) //fails
db.col.save({a:50}) //pass
db.col.save({a:50}) //fails
PS:也许您可以做些“ hack”并使用它:
partialFilterExpression: { serialNr: {$exists:true}, serialNr: {$gte:0} }
我尝试使用$ ne,但是这使我出错。
关于node.js - Mongoose 复合指数唯一+稀疏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35920733/