MongoDB如何为可空字段创建唯一索引及实现条件唯一约束
MongoDB 两个唯一性约束需求的实现方案
需求1:字段E非空时保证全局唯一,E为null时可正常插入多条数据
问题原因
你之前创建的普通唯一索引会将null视为有效值,全局仅允许存在1条E为null的文档,后续同条件数据插入会触发唯一键冲突。
解决方案:使用部分唯一索引
MongoDB 3.2及以上版本支持部分索引,可通过partialFilterExpression指定索引生效的过滤条件,仅满足条件的文档才会被纳入唯一约束校验。
Mongo Shell 执行命令
# 先删除之前创建的普通唯一索引 db.Order.dropIndex("E_1") # 创建部分唯一索引:仅当E存在且不为null时校验唯一性 db.Order.createIndex( { "E": 1 }, { unique: true, partialFilterExpression: { E: { $exists: true, $ne: null } } } )
Spring Data MongoDB 实体类注解写法
修改字段E的@Indexed注解即可,对应第二个需求的复合索引也可以同步在类上声明:
@Document // 第二个需求的复合部分唯一索引声明 @CompoundIndex(name = "d_f_unique_when_e_null", def = "{'D': 1, 'F': 1}", unique = true, partialFilter = "{ E: null }") public class Order { @Id private String id; @Indexed private String A; private String B; @Indexed private String C; @Indexed private String D; // 仅E非空时生效唯一约束 @Indexed(unique = true, partialFilter = "{ E: { $exists: true, $ne: null } }") private String E; private String F; }
需求2:仅当E为null时,校验D和F的组合唯一性
同样使用部分唯一索引实现,过滤条件指定E为null时,才对D和F的组合做唯一校验。
Mongo Shell 执行命令
db.Order.createIndex( { "D": 1, "F": 1 }, { unique: true, partialFilterExpression: { E: null } } )
该索引只会对E为null的文档校验D、F组合是否重复,E非空的文档不会纳入该约束的校验范围。
注意事项
创建索引前请先清理集合中已存在的、不符合约束规则的脏数据,否则会导致索引创建失败。
内容的提问来源于stack exchange,提问作者bootlover123
相关产品推荐
相关产品推荐

