Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bulk update for devices when type structure change #17

Open
andreareginato opened this issue Dec 4, 2012 · 0 comments
Open

Bulk update for devices when type structure change #17

andreareginato opened this issue Dec 4, 2012 · 0 comments

Comments

@andreareginato
Copy link
Contributor

One of the performance issues in Lelylan lies in the fact that when the type changes its properties, all devices properties needs to be updated (this doesn't smell good). This is a bad practice as the type should be living by its own and never be changed, but right now this could happen.

To solve this problem we experimented one shot query on mongodb, which we finally found out not being possible for now, as there is a BUG that will be solved only on version 2.3.2 (at the moment of writing we are at v2.2.0). Here is the code that should work for future improvements. For now we will simply work one record at time.

db.devices.find({ type_id: ObjectId("50bdcf90d033a95079000010"), 'properties.property_id': ObjectId("50bdcf90d033a95079000002") })

// update a value in the embedded document
db.devices.update(
   { type_id: ObjectId("50bdcf90d033a95079000010"), 'properties.property_id': ObjectId("50bdcf90d033a95079000002") },
   { $set: { 'properties.$.value': 'UPDATED' } },
   { multi: true }
)

// add a new embedded document 
db.devices.update(
   { type_id: ObjectId("50bdcf90d033a95079000010"), 'properties.property_id':  },
   { $push: { 'properties': { property_id: ObjectId("50bdcf90d033a95079000002"), value: 'ON' } } },
   { multi: true }
)

// remove an embedded document
db.devices.update(
   { type_id: ObjectId("50bdcf90d033a95079000010"), 'properties.property_id':  },
   { $pull: { 'properties': { property_id: ObjectId("50bdcf90d033a95079000002") } } },
   { multi: true }
)

Then, to add the code to MongoID you only need to call the collection method.

Device.collection.update(
   { type_id: Moped::BSON::ObjectId("50bdcf90d033a95079000010"), "properties.property_id" => Moped::BSON::ObjectId("50bdcf90d033a95079000002") },
   { "$set" => { "properties.$.value": "UPDATED" } },
   { multi: true }
)

To create the test suite run the following commands (a type must exist).

require 'factory_girl_rails'
u = FactoryGirl.create :user
type_id = Type.all.first.id
FactoryGirl.create :device, type:"http://api.lelylan.com/types/50bdcf90d033a95079000010", resource_owner_id: u.id, creator_id: u.id
FactoryGirl.create :device, type:"http://api.lelylan.com/types/50bdcf90d033a95079000010", resource_owner_id: u.id, creator_id: u.id
FactoryGirl.create :device, type:"http://api.lelylan.com/types/50bdcf90d033a95079000010", resource_owner_id: u.id, creator_id: u.id
Device.all.map(&:properties).map(&:first).map(&:value)

Learn more reading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant