Skip to content

Instantly share code, notes, and snippets.

@nwb
Created July 14, 2010 17:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nwb/475721 to your computer and use it in GitHub Desktop.
Save nwb/475721 to your computer and use it in GitHub Desktop.
{
name : "Something",
things : [
{foo : "148091a0719c", bar: 1},
{foo : "0026080741c6", bar: 0}
]
}
> db.test.find()
{ "_id" : ObjectId("4c3e933ccb3fdf086d596bd0"), "name" : "the_name", "things" : [
{
"foo" : "foo1",
"bar" : 4
},
{
"foo" : "foo2",
"bar" : 3
},
{
"foo" : "foo3",
"bar" : 3
},
{
"foo" : "foo4",
"bar" : 3
}
] }
> db.test.update({"name": "the_name", "things.foo": "foo2"},{"$set": {"things.$.bar": 12}})
can't append to array using string field name
>
require 'rubygems'
require 'mongo'
def add_name coll, nam
coll.update(
{"name" => nam, "things" => {"$size" =>0}},
{"name" => nam, "things"=> []},
:upsert => true)
end
def add_foo coll, nam, foo
add_name coll, nam
coll.update(
{"name" => nam, "things" => {"$not" => {"$elemMatch" => {"foo" => foo}}}},
{"$addToSet" => {"things" => {"foo" => foo, "bar" => 0}}})
end
def is_foo? coll, nam, foo
!!coll.find_one({"name" => nam, "things" => {"$elemMatch" => {"foo" => foo}}})
end
def increment_bar coll, nam, foo, inc=1
return false unless is_foo?(coll, nam, foo)
coll.update(
{"name" => nam, "things" => {"$elemMatch" => {"foo" => foo}}},
{"$inc" => {"things.$.bar" => inc}})
end
def set_level coll, name, lvl
s = coll.find_one({"name" => name})
count = s["things"].count
size, mod = lvl.divmod(count)
coll.find().each { |doc| puts doc.inspect }
s["things"].slice(0, mod).each do |thing|
coll.update(
{"name" => name, "things" => {"$elemMatch" => {"foo" => thing["foo"]}}},
{"$set" => {"things.$.bar" => size + 1}}
)
end
s["things"].slice(mod, count).each do |thing|
coll.update(
{"name" => name, "things" => {"$elemMatch" => {"foo" => thing["foo"]}}},
{"$set" => {"things.$.bar" => size}}
)
end
end
connect = Mongo::Connection.new()
db = connect.db("test")
collection = db.collection("test")
collection.remove()
collection.create_index([["name", Mongo::ASCENDING]], :unique=> true)
collection.create_index([["things.foo", Mongo::ASCENDING]], :unique=> true)
add_foo collection, "the_name", "foo1"
add_foo collection, "the_name", "foo2"
add_foo collection, "the_name", "foo3"
add_foo collection, "the_name", "foo1"
add_foo collection, "the_name", "foo4"
collection.find().each { |doc| puts doc.inspect }
set_level(collection, "the_name", 13)
collection.find().each { |doc| puts doc.inspect }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment