Mongoid:嵌入式文档的唯一索引

时间:2017-02-22 08:12:18

标签: ruby mongodb mongoid

我正在尝试为嵌入式文档创建一个唯一字段:

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有所帮助,但问题仍然存在

1 个答案:

答案 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)