From acdcf6a823b61e73347e5c86e77af9ec0ac6bab0 Mon Sep 17 00:00:00 2001 From: Kyle Banker Date: Fri, 19 Mar 2010 14:05:31 -0400 Subject: [PATCH] test demonstrating new features in 1.4 --- Rakefile | 5 + test/auxillary/1.4_features.rb | 166 +++++++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+) create mode 100644 test/auxillary/1.4_features.rb diff --git a/Rakefile b/Rakefile index c3ae028..40eb7d5 100644 --- a/Rakefile +++ b/Rakefile @@ -86,6 +86,11 @@ namespace :test do t.verbose = true end + Rake::TestTask.new(:new_features) do |t| + t.test_files = FileList['test/auxillary/1.4_features.rb'] + t.verbose = true + end + task :drop_databases do |t| puts "Dropping test database..." require File.join(File.dirname(__FILE__), 'lib', 'mongo') diff --git a/test/auxillary/1.4_features.rb b/test/auxillary/1.4_features.rb new file mode 100644 index 0000000..ec3adb7 --- /dev/null +++ b/test/auxillary/1.4_features.rb @@ -0,0 +1,166 @@ +$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) +require 'mongo' +require 'test/unit' +require 'test/test_helper' + +# Demonstrate features in MongoDB 1.4 +class Features14Test < Test::Unit::TestCase + + context "MongoDB 1.4" do + setup do + @con = Mongo::Connection.new + @db = @con['mongo-ruby-test'] + @col = @db['new-features'] + end + + teardown do + @col.drop + end + + context "new query operators: " do + + context "$elemMatch: " do + setup do + @col.save({:user => 'bob', :updates => [{:date => Time.now.utc, :body => 'skiing', :n => 1}, + {:date => Time.now.utc, :body => 'biking', :n => 2}]}) + + @col.save({:user => 'joe', :updates => [{:date => Time.now.utc, :body => 'skiing', :n => 2}, + {:date => Time.now.utc, :body => 'biking', :n => 10}]}) + end + + should "match a document with a matching object element in an array" do + doc = @col.find_one({"updates" => {"$elemMatch" => {"body" => "skiing", "n" => 2}}}) + assert_equal 'joe', doc['user'] + end + + should "$elemMatch with a conditional operator" do + doc1 = @col.find_one({"updates" => {"$elemMatch" => {"body" => "biking", "n" => {"$gt" => 5}}}}) + assert_equal 'joe', doc1['user'] + end + + should "note the difference between $elemMatch and a traditional match" do + doc = @col.find({"updates.body" => "skiing", "updates.n" => 2}).to_a + assert_equal 2, doc.size + end + end + + context "$all with regexes" do + setup do + @col.save({:n => 1, :a => 'whale'}) + @col.save({:n => 2, :a => 'snake'}) + end + + should "match multiple regexes" do + doc = @col.find({:a => {'$all' => [/ha/, /le/]}}).to_a + assert_equal 1, doc.size + assert_equal 1, doc.first['n'] + end + + should "not match if not every regex matches" do + doc = @col.find({:a => {'$all' => [/ha/, /sn/]}}).to_a + assert_equal 0, doc.size + end + end + + context "the $not operator" do + setup do + @col.save({:a => ['x']}) + @col.save({:a => ['x', 'y']}) + @col.save({:a => ['x', 'y', 'z']}) + end + + should "negate a standard operator" do + results = @col.find({:a => {'$not' => {'$size' => 2}}}).to_a + assert_equal 2, results.size + results = results.map {|r| r['a']} + assert_equal ['x'], results.sort.first + assert_equal ['x', 'y', 'z'], results.sort.last + end + end + end + + context "new update operators: " do + + context "$addToSet (pushing a unique value)" do + setup do + @col.save({:username => 'bob', :interests => ['skiing', 'guitar']}) + end + + should "add an item to a set uniquely ($addToSet)" do + @col.update({:username => 'bob'}, {'$addToSet' => {'interests' => 'skiing'}}) + @col.update({:username => 'bob'}, {'$addToSet' => {'interests' => 'kayaking'}}) + document = @col.find_one({:username => 'bob'}) + assert_equal ['guitar', 'kayaking', 'skiing'], document['interests'].sort + end + + should "add an array of items uniquely ($addToSet with $each)" do + @col.update({:username => 'bob'}, {'$addToSet' => {'interests' => {'$each' => ['skiing', 'kayaking', 'biking']}}}) + document = @col.find_one({:username => 'bob'}) + assert_equal ['biking', 'guitar', 'kayaking', 'skiing'], document['interests'].sort + end + end + + context "the positional operator ($)" do + setup do + @id1 = @col.insert({:text => 'hello', + :comments => [{'by' => 'bob', + 'text' => 'lol!'}, + {'by' => 'susie', + 'text' => 'bye bye!'}]}) + @id2 = @col.insert({:text => 'goodbye', + :comments => [{'by' => 'bob', + 'text' => 'au revoir'}, + {'by' => 'susie', + 'text' => 'bye bye!'}]}) + end + + should "update a matching array item" do + @col.update({"_id" => @id1, "comments.by" => 'bob'}, {'$set' => {'comments.$.text' => 'lmao!'}}, :multi => true) + result = @col.find_one({"_id" => @id1}) + assert_equal 'lmao!', result['comments'][0]['text'] + end + end + end + + context "Geoindexing" do + setup do + @places = @db['places'] + @places.create_index([['loc', Mongo::GEO2D]]) + + @empire_state = ([40.748371, -73.985031]) + @jfk = ([40.643711, -73.790009]) + + @places.insert({'name' => 'Empire State Building', 'loc' => ([40.748371, -73.985031])}) + @places.insert({'name' => 'Flatiron Building', 'loc' => ([40.741581, -73.987549])}) + @places.insert({'name' => 'Grand Central', 'loc' => ([40.751678, -73.976562])}) + @places.insert({'name' => 'Columbia University', 'loc' => ([40.808922, -73.961617])}) + @places.insert({'name' => 'NYSE', 'loc' => ([40.71455, -74.007124])}) + @places.insert({'name' => 'JFK', 'loc' => ([40.643711, -73.790009])}) + end + + teardown do + @places.drop + end + + should "find the nearest addresses" do + results = @places.find({'loc' => {'$near' => @empire_state}}).limit(2).to_a + assert_equal 2, results.size + assert_equal 'Empire State Building', results[0]['name'] + assert_equal 'Flatiron Building', results[1]['name'] + end + + should "use geoNear command to return distances from a point" do + cmd = OrderedHash.new + cmd['geoNear'] = 'places' + cmd['near'] = @empire_state + cmd['num'] = 6 + r = @db.command(cmd) + + assert_equal 6, r['results'].length + r['results'].each do |result| + puts result.inspect + end + end + end + end +end