Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to enforce unique embedded document in mongoid

I have the following model

class Person 
  include Mongoid::Document
  embeds_many :tasks
end

class Task
  include Mongoid::Document
  embedded_in :commit, :inverse_of => :tasks
  field :name
end

How can I ensure the following?

person.tasks.create :name => "create facebook killer"
person.tasks.create :name => "create facebook killer"

person.tasks.count == 1

different_person.tasks.create :name => "create facebook killer"
person.tasks.count == 1
different_person.tasks.count == 1

i.e. task names are unique within a particular person


Having checked out the docs on indexes I thought the following might work:

class Person 
  include Mongoid::Document
  embeds_many :tasks

  index [
      ["tasks.name", Mongo::ASCENDING], 
      ["_id", Mongo::ASCENDING]
  ], :unique => true
end

but

person.tasks.create :name => "create facebook killer"
person.tasks.create :name => "create facebook killer"

still produces a duplicate.


The index config shown above in Person would translate into for mongodb

db.things.ensureIndex({firstname : 1, 'tasks.name' : 1}, {unique : true})
like image 722
opsb Avatar asked Dec 02 '10 19:12

opsb


People also ask

How do I set unique values in MongoDB?

To create a unique index, use the db. collection. createIndex() method with the unique option set to true .

What does MongoDB enforce when setting a unique constraint on a compound index?

Introduction to MongoDB Unique. MongoDB's Unique Constraint makes certain that the fields indexed in it, do not store duplicate values for the same field, i.e., making sure the uniqueness of fields. By default, MongoDB enforces this unique constraint on the “_id” field, while inserting new data.

What is an embedded document in Nosql?

Embedded document or nested documents are those types of documents which contain a document inside another document.


2 Answers

Can't you just put a validator on the Task?

validates :name, :uniqueness => true

That should ensure uniqueness within parent document.

like image 145
Paul Elliott Avatar answered Sep 27 '22 23:09

Paul Elliott


Indexes are not unique by default. If you look at the Mongo Docs on this, uniqueness is an extra flag.

I don't know the exact Mongoid translation, but you're looking for something like this:

db.things.ensureIndex({firstname : 1}, {unique : true, dropDups : true})

like image 26
Gates VP Avatar answered Sep 27 '22 22:09

Gates VP