为了账号安全,请及时绑定邮箱和手机立即绑定

MongoDB:数组元素属性的唯一索引

/ 猿问

MongoDB:数组元素属性的唯一索引

一只甜甜圈 2019-10-21 14:34:27

我有一个类似的结构:


class Cat {

  int id;

  List<Kitten> kittens;

}


class Kitten {

  int id;

}

我想阻止用户创建一只猫,其中一只小猫的ID相同。我尝试过如下创建索引:


db.Cats.ensureIndex({'id': 1, 'kittens.id': 1}, {unique:true})

但是,当我尝试插入格式错误的猫时,Mongo接受了它。


我想念什么吗?甚至可以做到吗?


查看完整描述

3 回答

?
吃鸡游戏

据我所知,唯一索引仅在不同文档之间强制执行唯一性,因此这将引发重复的键错误:


db.cats.insert( { id: 123, kittens: [ { id: 456 } ] } )

db.cats.insert( { id: 123, kittens: [ { id: 456 } ] } )

但这是允许的:


db.cats.insert( { id: 123, kittens: [ { id: 456 }, { id: 456 } ] } )

我不确定是否有任何方法可以在Mongo级别强制执行您需要的约束,也许这是您可以在插入更新时在应用程序逻辑中检查的内容吗?


查看完整回答
反对 回复 2019-10-21
?
慕沐林林

确保数组字段中各个值的唯一性


除了上面的示例外,MongoDB中还有一个函数可确保在将新对象/值添加到数组字段时,仅在值/对象不存在时才执行更新。


因此,如果您有一个如下所示的文档:


{ _id: 123, kittens: [456] }

这将被允许:


db.cats.update({_id:123}, {$push: {kittens:456}})

导致


{ _id: 123, kittens: [456, 456] }

但是,使用$ addToSet函数(而不是$ push)将在添加值之前检查该值是否已经存在。因此,从以下内容开始:


{ _id: 123, kittens: [456] }

然后执行:


db.cats.update({_id:123}, {$addToSet: {kittens:456}})

不会有任何影响。


因此,长话短说,唯一约束不能验证数组字段的值项内的唯一性,只是两个文档在索引字段中不能具有相同的值。


查看完整回答
反对 回复 2019-10-21
?
慕标5265247

数组属性等效于具有唯一性的insert。下面的命令实际上是在确保小猫的唯一性的同时插入的(如果还没有123的对象,upsert会为您创建它)。


db.cats.update(

  { id: 123 },

  { $addToSet: {kittens: { $each: [ 456, 456] }}, $set: {'otherfields': 'extraval', "field2": "value2"}},

  { upsert: true}

)

对象的结果值将是


{

    "id": 123,

    "kittens": [456],

    "otherfields": "extraval",

    "field2": "value2"

}


查看完整回答
反对 回复 2019-10-21

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信