2

I am looking to add to multiple sets, and at the same time update the updated_at timestamp (touch). I could do this using the mongo driver:

db.mycollection.update({"_id": ObjectId("911")},
 {
  $addToSet: { "hashtags": {$each: ["#test1", "#test5"]}, "new_hash": {$each: ["test9"]} },
  $set: {"updated": "current time 3"}
 }
 )

How can I do this using mongoid in a rails app, in a single update query. Right now, I need to do 3 writes using mongoid:

my_object.add_to_set("hashtags", ["#test1", "#test5"])
my_object.add_to_set("new_hash", ["test9"])
my_object.touch
amit_saxena
  • 7,450
  • 5
  • 49
  • 64
  • Mongoid doesn't give much flexibility regarding the queries you can perform. IMO it would be much better to use the official mongo driver and not mongoid (which uses its own driver, Moped). – Agis Oct 23 '13 at 10:40

2 Answers2

2

You must use Moped, the Mongoid Driver (docs here: http://mongoid.org/en/moped/docs/driver.html).

something like this should do the trick:

my_query = {
 '$addToSet' => { "hashtags" => {'$each' => ["#test1", "#test5"]}, "new_hash" => {'$each' => ["test9"]} },
 '$set' => {"ts" => Time.now}
}
MyClass.collection.find('_id' => my_object.id).update(my_query)
amit_saxena
  • 7,450
  • 5
  • 49
  • 64
Enrique Fueyo
  • 3,358
  • 1
  • 16
  • 10
0

I am not sure, but if you do this:

my_object.hashtags += ["#test1", "#test5"]
my_object.new_hash += ["test9"]
my_object.save

I think that it only writes one time and the updated_at field is updated automatically.

rjurado01
  • 5,337
  • 3
  • 36
  • 45
  • I want it to be atomic, as there could be concurrent requests doing that. In this approach, if 2 reads happen at the same time, then the one writing later will persist the array, resulting in loss of data. Also $addToSet adds only if the element doesn't exist (which can be programmatically achieved in the app as well, but it's good to have it out of the box). – amit_saxena Oct 23 '13 at 11:32