我正在尝试为嵌入式文档创建一个唯一字段:
class Chapter
include Mongoid::Document
field :title
end
class Book
include Mongoid::Document
field :name
embeds_many :chapters
index({ 'name' => 1 }, { unique: true })
index({ 'name' => 1, 'chapters.title' => 1 }, { unique: true, sparse: true })
# index({ 'name' => 1, 'chapters.title' => 1 }, { unique: true })
end
我执行任务:rake db:mongoid:create_indexes
I, [2017-02-22T08:56:47.087414 #94935] INFO -- : MONGOID: Created indexes on Book:
I, [2017-02-22T08:56:47.087582 #94935] INFO -- : MONGOID: Index: {:name=>1}, Options: {:unique=>true}
I, [2017-02-22T08:56:47.087633 #94935] INFO -- : MONGOID: Index: {:name=>1, :"chapters.title"=>1}, Options: {:unique=>true, :sparse=>true}
但它没有像我期望的那样起作用......
Book.new( name: 'A book', chapters: [ { title: 'title1' }, { title: 'title1' }, { title: 'title2' } ] ).save # no errors
Book.new( name: 'Another book', chapters: [ { title: 'title2' } ] ).save
b = Book.last
b.chapters.push( Chapter.new( { title: 'title2' } ) )
b.save # no errors
有什么想法吗?
更新:Ruby 2.4.0,Mongo 3.2.10,Mongoid 5.2.0 | 6.0.3(尝试两者)
UPDATE2:我还添加了我用mongo客户端直接进行的测试:
use books
db.books.ensureIndex({ title: 1 }, { unique: true })
db.books.ensureIndex({ "title": 1, "chapters.title": 1 }, { unique: true, sparse: true, drop_dups: true })
db.books.insert({ title: "Book1", chapters: [ { title: "Ch1" }, { title: "Ch1" } ] }) # allowed?!
db.books.insert({ title: "Book1", chapters: [ { title: "Ch1" } ] })
b = db.books.findOne( { title: 'Book1' } )
b.chapters.push( { "title": "Ch1" } )
db.books.save( b ) # allowed?!
db.books.findOne( { title: 'Book1' } )
db.books.insert({ title: "Book2", chapters: [ { title: "Ch1" } ] })
更新3:我做了更多测试,但我没有成功,这link有所帮助,但问题仍然存在
答案 0 :(得分:-1)
您应该使用 drop_dups
class Category
include Mongoid::Document
field :title, type: String
embeds_many :posts
index({"posts.title" => 1}, {unique: true, drop_dups: true, name: 'unique_drop_dulp_idx'})
end
class Post
include Mongoid::Document
field :title, type: String
end
Rails控制台:
irb(main):032:0> Category.first.posts.create(title: 'Honda S2000')
=> #<Post _id: 58adb923cacaa6f778215a26, title: "Honda S2000">
irb(main):033:0> Category.first.posts.create(title: 'Honda S2000')
Mongo::Error::OperationFailure: E11000 duplicate key error collection: mo_development.posts index: title_1 dup key: { : "Honda S2000" } (11000)