mongo 1.7.1 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. data/{LICENSE.txt → LICENSE} +0 -0
  2. data/README.md +124 -111
  3. data/Rakefile +9 -325
  4. data/VERSION +1 -0
  5. data/bin/mongo_console +4 -4
  6. data/examples/admin.rb +43 -0
  7. data/examples/capped.rb +22 -0
  8. data/examples/cursor.rb +48 -0
  9. data/examples/gridfs.rb +44 -0
  10. data/examples/index_test.rb +126 -0
  11. data/examples/info.rb +31 -0
  12. data/examples/queries.rb +74 -0
  13. data/examples/replica_set.rb +26 -0
  14. data/examples/simple.rb +25 -0
  15. data/examples/strict.rb +35 -0
  16. data/examples/types.rb +36 -0
  17. data/{test/load → examples/web}/thin/load.rb +3 -1
  18. data/{test/load → examples/web}/unicorn/load.rb +5 -3
  19. data/lib/mongo.rb +8 -10
  20. data/lib/mongo/collection.rb +134 -114
  21. data/lib/mongo/cursor.rb +21 -14
  22. data/lib/mongo/db.rb +30 -28
  23. data/lib/mongo/exceptions.rb +1 -1
  24. data/lib/mongo/gridfs/grid.rb +8 -7
  25. data/lib/mongo/gridfs/grid_ext.rb +1 -1
  26. data/lib/mongo/gridfs/grid_file_system.rb +6 -5
  27. data/lib/mongo/gridfs/grid_io.rb +22 -19
  28. data/lib/mongo/legacy.rb +82 -0
  29. data/lib/mongo/{connection.rb → mongo_client.rb} +82 -61
  30. data/lib/mongo/{repl_set_connection.rb → mongo_replica_set_client.rb} +54 -39
  31. data/lib/mongo/{sharded_connection.rb → mongo_sharded_client.rb} +9 -9
  32. data/lib/mongo/networking.rb +25 -20
  33. data/lib/mongo/util/conversions.rb +1 -1
  34. data/lib/mongo/util/core_ext.rb +1 -1
  35. data/lib/mongo/util/logging.rb +20 -4
  36. data/lib/mongo/util/node.rb +16 -16
  37. data/lib/mongo/util/pool.rb +56 -27
  38. data/lib/mongo/util/pool_manager.rb +28 -27
  39. data/lib/mongo/util/server_version.rb +1 -1
  40. data/lib/mongo/util/sharding_pool_manager.rb +8 -8
  41. data/lib/mongo/util/ssl_socket.rb +1 -5
  42. data/lib/mongo/util/support.rb +24 -8
  43. data/lib/mongo/util/tcp_socket.rb +0 -4
  44. data/lib/mongo/util/uri_parser.rb +54 -38
  45. data/lib/mongo/util/write_concern.rb +67 -0
  46. data/mongo.gemspec +21 -32
  47. data/test/auxillary/{1.4_features.rb → 1.4_feature_test.rb} +4 -5
  48. data/test/auxillary/authentication_test.rb +18 -20
  49. data/test/auxillary/autoreconnect_test.rb +3 -5
  50. data/test/auxillary/fork_test.rb +5 -7
  51. data/test/auxillary/repl_set_auth_test.rb +13 -15
  52. data/test/auxillary/slave_connection_test.rb +8 -7
  53. data/test/auxillary/threaded_authentication_test.rb +15 -17
  54. data/test/bson/binary_test.rb +1 -1
  55. data/test/bson/bson_test.rb +60 -36
  56. data/test/bson/byte_buffer_test.rb +1 -1
  57. data/test/bson/hash_with_indifferent_access_test.rb +2 -2
  58. data/test/bson/json_test.rb +1 -2
  59. data/test/bson/object_id_test.rb +1 -2
  60. data/test/bson/ordered_hash_test.rb +1 -1
  61. data/test/bson/timestamp_test.rb +1 -1
  62. data/test/{collection_test.rb → functional/collection_test.rb} +57 -57
  63. data/test/{connection_test.rb → functional/connection_test.rb} +75 -89
  64. data/test/{conversions_test.rb → functional/conversions_test.rb} +1 -1
  65. data/test/{cursor_fail_test.rb → functional/cursor_fail_test.rb} +3 -29
  66. data/test/{cursor_message_test.rb → functional/cursor_message_test.rb} +1 -1
  67. data/test/{cursor_test.rb → functional/cursor_test.rb} +5 -1
  68. data/test/{db_api_test.rb → functional/db_api_test.rb} +8 -9
  69. data/test/{db_connection_test.rb → functional/db_connection_test.rb} +3 -5
  70. data/test/{db_test.rb → functional/db_test.rb} +13 -13
  71. data/test/{grid_file_system_test.rb → functional/grid_file_system_test.rb} +2 -2
  72. data/test/{grid_io_test.rb → functional/grid_io_test.rb} +6 -6
  73. data/test/{grid_test.rb → functional/grid_test.rb} +4 -10
  74. data/test/{pool_test.rb → functional/pool_test.rb} +1 -1
  75. data/test/functional/safe_test.rb +84 -0
  76. data/test/{support_test.rb → functional/support_test.rb} +1 -1
  77. data/test/{threading_test.rb → functional/threading_test.rb} +9 -9
  78. data/test/{timeout_test.rb → functional/timeout_test.rb} +1 -1
  79. data/test/{uri_test.rb → functional/uri_test.rb} +1 -1
  80. data/test/functional/write_concern_test.rb +104 -0
  81. data/test/replica_set/basic_test.rb +139 -0
  82. data/test/replica_set/client_test.rb +255 -0
  83. data/test/replica_set/complex_connect_test.rb +62 -0
  84. data/test/replica_set/connection_test.rb +255 -0
  85. data/test/{replica_sets → replica_set}/count_test.rb +17 -14
  86. data/test/replica_set/cursor_test.rb +75 -0
  87. data/test/{replica_sets → replica_set}/insert_test.rb +19 -16
  88. data/test/replica_set/query_test.rb +64 -0
  89. data/test/replica_set/refresh_test.rb +153 -0
  90. data/test/{replica_sets → replica_set}/replication_ack_test.rb +21 -17
  91. data/test/sharded_cluster/basic_test.rb +31 -50
  92. data/test/support/hash_with_indifferent_access.rb +1 -1
  93. data/test/test_helper.rb +56 -9
  94. data/test/threading/threading_with_large_pool_test.rb +8 -8
  95. data/test/tools/mongo_config.rb +270 -58
  96. data/test/tools/mongo_config_test.rb +146 -0
  97. data/test/unit/client_test.rb +230 -0
  98. data/test/unit/collection_test.rb +45 -32
  99. data/test/unit/connection_test.rb +82 -74
  100. data/test/unit/cursor_test.rb +14 -6
  101. data/test/unit/db_test.rb +8 -8
  102. data/test/unit/grid_test.rb +11 -11
  103. data/test/unit/node_test.rb +24 -24
  104. data/test/unit/pool_manager_test.rb +13 -13
  105. data/test/unit/pool_test.rb +1 -1
  106. data/test/unit/read_test.rb +21 -26
  107. data/test/unit/safe_test.rb +52 -33
  108. data/test/unit/util_test.rb +55 -0
  109. data/test/unit/write_concern_test.rb +161 -0
  110. metadata +158 -171
  111. data/docs/CREDITS.md +0 -123
  112. data/docs/FAQ.md +0 -116
  113. data/docs/GRID_FS.md +0 -158
  114. data/docs/HISTORY.md +0 -392
  115. data/docs/READ_PREFERENCE.md +0 -99
  116. data/docs/RELEASES.md +0 -54
  117. data/docs/REPLICA_SETS.md +0 -113
  118. data/docs/TAILABLE_CURSORS.md +0 -51
  119. data/docs/TUTORIAL.md +0 -356
  120. data/docs/WRITE_CONCERN.md +0 -31
  121. data/lib/mongo/gridfs/grid_io_fix.rb +0 -38
  122. data/lib/mongo/version.rb +0 -3
  123. data/test/bson/test_helper.rb +0 -30
  124. data/test/replica_sets/basic_test.rb +0 -119
  125. data/test/replica_sets/complex_connect_test.rb +0 -57
  126. data/test/replica_sets/complex_read_preference_test.rb +0 -237
  127. data/test/replica_sets/connect_test.rb +0 -156
  128. data/test/replica_sets/cursor_test.rb +0 -70
  129. data/test/replica_sets/pooled_insert_test.rb +0 -57
  130. data/test/replica_sets/query_test.rb +0 -50
  131. data/test/replica_sets/read_preference_test.rb +0 -234
  132. data/test/replica_sets/refresh_test.rb +0 -156
  133. data/test/replica_sets/refresh_with_threads_test.rb +0 -60
  134. data/test/replica_sets/rs_test_helper.rb +0 -39
  135. data/test/safe_test.rb +0 -68
  136. data/test/sharded_cluster/mongo_config_test.rb +0 -126
  137. data/test/sharded_cluster/sc_test_helper.rb +0 -39
  138. data/test/tools/repl_set_manager.rb +0 -418
@@ -1,99 +0,0 @@
1
- # Read Preference in Ruby
2
-
3
- ## About Read Preference
4
-
5
- Read preferences determine the candidate replica set members to which a query or command can be sent. They consist of a *mode* specified as a symbol and an array of hashes known as *tag_sets*.
6
-
7
- Read preference mode is configured by providing the read option to a connection, database, collection, or cursor.
8
-
9
- @collection.find({:doc => 'foo'}, :read => :primary) # read from primary only
10
- @collection.find({:doc => 'foo'}, :read => :secondary) # read from secondaries only
11
-
12
- Used in conjunction with tag_sets:
13
-
14
- @collection.find({:name => 'foo'}, :read => :secondary_preferred, :tag_sets => [{:continent => 'USA'}])
15
-
16
- *Please Note*: Behavior of some read preference modes have changed in version 1.7.0:
17
-
18
- * `:secondary_preferred` mode is now used to prefer reads from secondary members (before this was the behavior of `:secondary`).
19
- * `:secondary_only` mode (which only allowed reads from secondaries) is now called `:secondary`.
20
-
21
- ## Read preference inheritance
22
-
23
- The Ruby driver allows you to set read preference on each of four levels: the connection, database, collection, and cursor (or read operation).
24
- Objects will inherit the default read preference from their parents. Thus, if you set a read preference of `{:read => :secondary}` when creating
25
- a new connection, then all databases and collections created from that connection will inherit the same setting. See this code example:
26
-
27
- @con = Mongo::ReplSetConnection.new(['localhost:27017','localhost:27018'], :read => :secondary)
28
- @db = @con['test']
29
- @collection = @db['foo']
30
- @collection.find({:name => 'foo'})
31
-
32
- @collection.find({:name => 'bar'}, :read => :primary)
33
-
34
- Here, the first call to Collection#find will use the inherited read preference, `{:read => :secondary}`. But the second call
35
- to Collection#find overrides this setting by setting the preference to `:primary`.
36
-
37
- You can examine the read preference on any object by calling its `read_preference` method:
38
-
39
- @con.read_preference
40
- @db.read_preference
41
- @collection.read_preference
42
-
43
- ## Modes
44
-
45
- You can using the `:read` option to specify a query's read preference mode. There are five possible options.
46
-
47
- ### :primary
48
-
49
- With primary, all read operations from the client will use the primary member only. This is the default read preference.
50
-
51
- If the primary is unavailable, all operations with this preference produce an error or throw an exception. Primary read preference modes are not compatible with read preferences modes that use tag sets If you specify a tag set with primary, the driver will produce an error.
52
-
53
- ### :primary_preferred
54
-
55
- With the primaryPreferred read preference mode, operations will read from the primary member of the set in most situations. However, if the primary is unavailable, as is the case during failover situations, then these read operations can read from secondary members.
56
-
57
- When the read preference includes a tag set, the client will first read from the primary, if it is available, and then from secondaries that match the specified tags. If there are no secondaries with tags that match the specified tags, this read operation will produce an error.
58
-
59
- ### :secondary
60
-
61
- With the secondary read preference mode, operations will read from the secondary member of the set if available. However, if there are no secondaries available, then these operations will produce an error or exception.
62
-
63
- Most sets have at least one secondary, but there are situations where there may not be an available secondary. For example, a set with a primary, a secondary, and an arbiter may not have any secondaries if a member is ever in recovering mode.
64
-
65
- When the read preference includes a tag set, the client will attempt to find a secondary members that match the specified tag set and directs reads to a random secondary from among the nearest group. If there are no secondaries with tags that match the specified tag set, this read operation will produce an error.
66
-
67
- ### :secondary_preferred
68
-
69
- With the secondaryPreferred, operations will read from secondary members, but in situations where the set only has a primary instance, the read operation will use the set’s primary.
70
-
71
- When secondaryPreferred reads from a secondary and the read preference includes a tag set, the client will attempt to find a secondary members that match the specified tag set and directs reads to a random secondary from among the nearest group. If there are no secondaries with tags that match the specified tag set, this read operation will produce an error.
72
-
73
- ### :nearest
74
-
75
- With the nearest, the driver will read from the nearest member of the set according to the member selection process nearest read operations will not have any consideration for the type of the set member. Reads in nearest mode may read from both primaries and secondaries.
76
-
77
- Set this mode when you want minimize the effect of network latency on read operations without preference for current or stale data.
78
-
79
- If you specify a tag set, the client will attempt to find a secondary members that match the specified tag set and directs reads to a random secondary from among the nearest group.
80
-
81
- ## Tag Sets
82
-
83
- Tag sets can be used in for data center awareness by filtering secondary read operations. Primary reads occur independent of any tags.
84
-
85
- A member matches a tag set if its tags match all the tags in the set. For example, a member tagged "{ dc: 'ny', rack: 2, size: 'large' }" matches the tag set "{ dc: 'ny', rack: 2 }". A member's extra tags don't affect whether it's a match.
86
-
87
- Here is an example of a query which sends read operations to members in rack 2.
88
-
89
- @collection.find({:name => 'foo'}, :read => :secondary_preferred, :tag_sets => [{:rack => '2'}])
90
-
91
- Tag set keys may be symbols or strings. Tag set values should be specified using strings. The `to_s` method will be called on any values provided in the tag set.
92
-
93
- Tag sets are used in conjunction with read preference mode. In this example, because we specified a mode of secondary_preferred, if no secondaries can be found that match the tag_set `{:rack => '2'}` then the primary will be used for the query.
94
-
95
- If only one tag set is provided, the set can be passed as a single hash parameter iteself without the enclosing array.
96
-
97
- @collection.find({:name => 'foo'}, :read => :secondary_preferred, :tag_sets => {:rack => '2'})
98
-
99
- Specifiying tag_sets for mode `:primary` is considered an error and will raise a MongoArgumentError as tag_sets do not affect selection of primary members and only primary members can be selected in that particular mode.
@@ -1,54 +0,0 @@
1
- # MongoDB Ruby Driver Release Plan
2
-
3
- This is a description of a formalized release plan that will take effect
4
- with version 1.3.0.
5
-
6
- ## Semantic versioning
7
-
8
- The most significant difference is that releases will now adhere to the conventions of
9
- [semantic versioning](http://semver.org). In particular, we will strictly abide by the
10
- following release rules:
11
-
12
- 1. Patch versions of the driver (Z in x.y.Z) will be released only when backward-compatible bug fixes are introduced. A bug fix is defined as an internal change that fixes incorrect behavior.
13
-
14
- 2. Minor versions (Y in x.Y.z) will be released if new, backward-compatible functionality is introduced to the public API.
15
-
16
- 3. Major versions (X in X.y.z) will be incremented if any backward-incompatible changes are introduced to the public API.
17
-
18
- This policy will clearly indicate to users when an upgrade may affect their code. As a side effect, version numbers will climb more quickly than before.
19
-
20
-
21
- ## Release checklist
22
-
23
- Before each relese to Rubygems.org, the following steps will be taken:
24
-
25
- 1. All driver tests will be run on Linux, OS X, and Windows via continuous integration system.
26
-
27
- 2. Update the HISTORY file and document all significant commits.
28
-
29
- 3. Update the version in lib/bson.rb, lib/mongo/version.rb, and ext/cbson/version.h.
30
-
31
- 4. Commit: "RELEASE [VERSION]"
32
-
33
- 5. git tag [version]
34
-
35
- 6. Build gems. Ensure that they have the correct versions.
36
-
37
- 7. Push tags and commit to GitHub (git push origin master, git push --tags).
38
-
39
- 8. Build and push docs. (git: mongodb/apidocs)
40
-
41
- 9. Push gems to Rubygems.org.
42
-
43
- 10. Test that the gem is downloadable from Rubygems.org.
44
-
45
- 11. Close out release in JIRA.
46
-
47
- 12. Annouce release on mongodb-user and mongodb-dev.
48
-
49
- ## Rake Deploy Tasks
50
- 1. rake deploy:change_version[x.x.x]
51
- 2. rake deploy:git_prepare
52
- 3. rake deploy:git_push
53
- 4. rake deploy:gem_build
54
- 5. rake deploy:gem_push
@@ -1,113 +0,0 @@
1
- # Replica Sets in Ruby
2
-
3
- Here follow a few considerations for those using the MongoDB Ruby driver with [replica sets](http://www.mongodb.org/display/DOCS/Replica+Sets).
4
-
5
- ### Setup
6
-
7
- First, make sure that you've configured and initialized a replica set.
8
-
9
- Use `ReplSetConnection.new` to connect to a replica set. This method, which accepts a variable number of arugments,
10
- takes a list of seed nodes followed by any connection options. You'll want to specify at least two seed nodes. This gives
11
- the driver more chances to connect in the event that any one seed node is offline. Once the driver connects, it will
12
- cache the replica set topology as reported by the given seed node and use that information if a failover is later required.
13
-
14
- @connection = ReplSetConnection.new(['n1.mydb.net:27017', 'n2.mydb.net:27017', 'n3.mydb.net:27017'])
15
-
16
- ### Read slaves
17
-
18
- If you want to read from a secondary node, you can pass :read => :secondary to ReplSetConnection#new.
19
-
20
- @connection = ReplSetConnection.new(['n1.mydb.net:27017', 'n2.mydb.net:27017', 'n3.mydb.net:27017'],
21
- :read => :secondary)
22
-
23
- A random secondary will be chosen to be read from. In a typical multi-process Ruby application, you'll have a good distribution of reads across secondary nodes.
24
-
25
- ### Connection Failures
26
-
27
- Imagine that either the master node or one of the read nodes goes offline. How will the driver respond?
28
-
29
- If any read operation fails, the driver will raise a *ConnectionFailure* exception. It then becomes the client's responsibility to decide how to handle this.
30
-
31
- If the client decides to retry, it's not guaranteed that another member of the replica set will have been promoted to master right away, so it's still possible that the driver will raise another *ConnectionFailure*. However, once a member has been promoted to master, typically within a few seconds, subsequent operations will succeed. *Note that this does not prevent
32
- exception in the event of a primary failover.*
33
-
34
- The driver will essentially cycle through all known seed addresses until a node identifies itself as master.
35
-
36
- ### Refresh mode
37
-
38
- You can now specify a refresh mode and refresh interval for a replica set connection. This will help to ensure that
39
- changes to a replica set's configuration are quickly reflected on the driver side. In particular, if you change
40
- the state of any secondary node, the automated refresh will ensure that this state is recorded on the client side.
41
-
42
- There are two secenarios in which refresh is helpful and does not raise exceptions:
43
-
44
- 1. You add a new secondary node to an existing replica set
45
- 2. You remove an unused secondary from an existing replica set
46
-
47
- If using MongoDB earlier than 2.0 any changes to replica set state will raise exceptions therefore refresh mode will not be useful.
48
-
49
- If you add a secondary that responds to pings much faster than the existing nodes, then the new secondary will
50
- be used for reads if :read_preference is :secondary or :secondary_only
51
-
52
- Refresh mode is disabled by default.
53
-
54
- However, if you expect to make live changes to your secondaries, and you want this to be reflected without
55
- having to manually restart your app server, then you should enable it. You can enable this mode
56
- synchronously, which will refresh the replica set data in a synchronous fashion (which may
57
- ocassionally slow down your queries):
58
-
59
- @connection = ReplSetConnection.new(['n1.mydb.net:27017'], :refresh_mode => :sync)
60
-
61
- If you want to change the default refresh interval of 90 seconds, you can do so like this:
62
-
63
- @connection = ReplSetConnection.new(['n1.mydb.net:27017'], :refresh_mode => :sync,
64
- :refresh_interval => 60)
65
-
66
- Do not set this value to anything lower than 30, or you may start to experience performance issues.
67
-
68
- You can also disable refresh mode altogether:
69
-
70
- @connection = ReplSetConnection.new(['n1.mydb.net:27017'], :refresh_mode => false)
71
-
72
- And you can call `refresh` manually on any replica set connection:
73
-
74
- @connection.refresh
75
-
76
- ### Recovery
77
-
78
- Driver users may wish to wrap their database calls with failure recovery code. Here's one possibility, which will attempt to connection
79
- every half second and time out after thirty seconds.
80
-
81
- # Ensure retry upon failure
82
- def rescue_connection_failure(max_retries=60)
83
- retries = 0
84
- begin
85
- yield
86
- rescue Mongo::ConnectionFailure => ex
87
- retries += 1
88
- raise ex if retries > max_retries
89
- sleep(0.5)
90
- retry
91
- end
92
- end
93
-
94
- # Wrapping a call to #count()
95
- rescue_connection_failure do
96
- @db.collection('users').count()
97
- end
98
-
99
- Of course, the proper way to handle connection failures will always depend on the individual application. We encourage object-mapper and application developers to publish any promising results.
100
-
101
- ### Testing
102
-
103
- The Ruby driver (>= 1.1.5) includes unit tests for verifying replica set behavior. They reside in *tests/replica_sets*. You can run them as a group with the following rake task:
104
-
105
- rake test:rs
106
-
107
- The suite will set up a five-node replica set by itself and ensure that driver behaves correctly even in the face
108
- of individual node failures. Note that the `mongod` executable must be in the search path for this to work.
109
-
110
- ### Further Reading
111
-
112
- * [Replica Sets](http://www.mongodb.org/display/DOCS/Replica+Set+Configuration)
113
- * [Replics Set Configuration](http://www.mongodb.org/display/DOCS/Replica+Set+Configuration)
@@ -1,51 +0,0 @@
1
- # Tailable cursors in Ruby
2
-
3
- Tailable cursors are cursors that remain open even after they've returned
4
- a final result. This way, if more documents are added to a collection (i.e.,
5
- to the cursor's result set), then you can continue to call `Cursor#next` to
6
- retrieve those results. Here's a complete test case that demonstrates the use
7
- of tailable cursors.
8
-
9
- Note that tailable cursors are for capped collections only.
10
-
11
- require 'mongo'
12
- require 'test/unit'
13
-
14
- class TestTailable < Test::Unit::TestCase
15
- include Mongo
16
-
17
- def test_tailable
18
-
19
- # Create a connection and capped collection.
20
- @con = Connection.new
21
- @db = @con['test']
22
- @db.drop_collection('log')
23
- @capped = @db.create_collection('log', :capped => true, :size => 1024)
24
-
25
- # Insert 10 documents.
26
- 10.times do |n|
27
- @capped.insert({:n => n})
28
- end
29
-
30
- # Create a tailable cursor that iterates the collection in natural order
31
- @tail = Cursor.new(@capped, :tailable => true, :order => [['$natural', 1]])
32
-
33
- # Call Cursor#next 10 times. Each call returns a document.
34
- 10.times do
35
- assert @tail.next
36
- end
37
-
38
- # But the 11th time, the cursor returns nothing.
39
- assert_nil @tail.next
40
-
41
- # Add a document to the capped collection.
42
- @capped.insert({:n => 100})
43
-
44
- # Now call Cursor#next again. This will return the just-inserted result.
45
- assert @tail.next
46
-
47
- # Close the cursor.
48
- @tail.close
49
- end
50
-
51
- end
@@ -1,356 +0,0 @@
1
- # MongoDB Ruby Driver Tutorial
2
-
3
- This tutorial gives many common examples of using MongoDB with the Ruby driver. If you're looking for information on data modeling, see [MongoDB Data Modeling and Rails](http://www.mongodb.org/display/DOCS/MongoDB+Data+Modeling+and+Rails). Links to the various object mappers are listed on our [object mappers page](http://www.mongodb.org/display/DOCS/Object+Mappers+for+Ruby+and+MongoDB).
4
-
5
- Interested in GridFS? See [GridFS in Ruby](file.GridFS.html).
6
-
7
- As always, the [latest source for the Ruby driver](http://github.com/mongodb/mongo-ruby-driver) can be found on [github](http://github.com/mongodb/mongo-ruby-driver/).
8
-
9
- ## Installation
10
-
11
- The mongo-ruby-driver gem is served through Rubygems.org. To install, make sure you have the latest version of rubygems.
12
-
13
- gem update --system
14
-
15
- Next, install the mongo rubygem:
16
-
17
- gem install mongo
18
-
19
- The required `bson` gem will be installed automatically.
20
-
21
- For optimum performance, install the bson\_ext gem:
22
-
23
- gem install bson_ext
24
-
25
- After installing, you may want to look at the [examples](http://github.com/mongodb/mongo-ruby-driver/tree/master/examples) directory included in the source distribution. These examples walk through some of the basics of using the Ruby driver.
26
-
27
- ## Getting started
28
-
29
- Note that the output in the following has been updated to Ruby 1.9, so if you are using Ruby 1.8, you will see some minor differences. To follow this tutorial interactively, at the command line, run the Interactive Ruby Shell.
30
-
31
- irb
32
-
33
- As you execute commands, irb will output the result using the `inspect` method. If you are editing and running a script for this tutorial, you can view output using the `puts` or `p` methods.
34
-
35
- ### Using the gem
36
-
37
- Use the `mongo` gem via the `require` kernel method.
38
-
39
- require 'rubygems' # not necessary for Ruby 1.9
40
- require 'mongo'
41
-
42
- ### Making a Connection
43
-
44
- An `Mongo::Connection` instance represents a connection to MongoDB. You can optionally specify the MongoDB server address and port when connecting. The following example shows three ways to connect to the local machine:
45
-
46
- connection = Mongo::Connection.new # (optional host/port args)
47
- connection = Mongo::Connection.new("localhost")
48
- connection = Mongo::Connection.new("localhost", 27017)
49
-
50
- ### Listing All Databases
51
-
52
- connection.database_names
53
- connection.database_info.each { |info| puts info.inspect }
54
-
55
- The `database_info` method returns a hash mapping database names to the size of the database in bytes.
56
-
57
- ## Using a Database
58
-
59
- You use a Connection instance to obtain an Mongo::DB instance, which represents a named database. The database doesn't have to exist - if it doesn't, MongoDB will create it for you. The following examples use the database "mydb":
60
-
61
- db = connection.db("mydb")
62
- db = Mongo::Connection.new.db("mydb")
63
-
64
- At this point, the `db` object will be a connection to a MongoDB server for the specified database. Each DB instance uses a separate socket connection to the server.
65
-
66
- If you're trying to connect to a replica set, see [Replica Sets in Ruby](http://www.mongodb.org/display/DOCS/Replica+Sets+in+Ruby).
67
-
68
- ### Authentication
69
-
70
- MongoDB can be run in a secure mode where access to databases is controlled through name and password authentication. When run in this mode, any client application must provide a name and password before doing any operations. In the Ruby driver, you simply do the following with the connected mongo object:
71
-
72
- auth = db.authenticate(my_user_name, my_password)
73
-
74
- If the name and password are valid for the database, `auth` will be `true`. Otherwise, it will be `false`. You should look at the MongoDB log for further information if available.
75
-
76
- ## Using a Collection
77
-
78
- You can get a collection to use using the `collection` method:
79
-
80
- coll = db.collection("testCollection")
81
-
82
- This is aliased to the \[\] method:
83
-
84
- coll = db["testCollection"]
85
-
86
- Once you have this collection object, you can now do create, read, update, and delete (CRUD) functions on persistent storage.
87
-
88
- ### Creating Documents with `insert`
89
-
90
- Once you have the collection object, you can create or `insert` documents into the collection. For example, lets make a little document that in JSON would be represented as
91
-
92
- {
93
- "name" : "MongoDB",
94
- "type" : "database",
95
- "count" : 1,
96
- "info" : {
97
- x : 203,
98
- y : 102
99
- }
100
- }
101
-
102
- Notice that the above has an "inner" document embedded within it. To do this, we can use a Hash or the driver's OrderedHash (which preserves key order) to create the document (including the inner document), and then just simply insert it into the collection using the `insert` method.
103
-
104
- doc = {"name" => "MongoDB", "type" => "database", "count" => 1, "info" => {"x" => 203, "y" => '102'}}
105
- id = coll.insert(doc)
106
-
107
- We have saved the `id` for future use below. Now the collection has been created and you can list it.
108
-
109
- #### Getting a List Of Collections
110
-
111
- Each database has zero or more collections. You can retrieve a list of them from the db (and print out any that are there):
112
-
113
- db.collection_names
114
-
115
- You should see
116
-
117
- \["testCollection", "system.indexes"\]
118
-
119
- #### Adding Multiple Documents
120
-
121
- To demonstrate some more interesting queries, let's add multiple simple documents to the collection. These documents will have the following form:
122
-
123
- {
124
- "i" : value
125
- }
126
-
127
- Here's how to insert them:
128
-
129
- 100.times { |i| coll.insert("i" => i) }
130
-
131
- Notice that we can insert documents of different "shapes" into the same collection. These records are in the same collection as the complex record we inserted above. This aspect is what we mean when we say that MongoDB is "schema-free".
132
-
133
- ### Reading Documents with `find_one` and `find`
134
-
135
- #### Reading the First Document in a Collection using `find_one`
136
-
137
- To retrieve the document that we inserted, we can do a simple `find_one` method to get the first document in the collection. This method returns a single document directly.
138
-
139
- coll.find_one
140
-
141
- and you should something like:
142
-
143
- {"_id"=>BSON::ObjectId('4f7b1ea6e4d30b35c9000001'), "name"=>"MongoDB", "type"=>"database", "count"=>1, "info"=>{"x"=>203, "y"=>"102"}}
144
-
145
- Note the `_id` element has been added automatically by MongoDB to your document.
146
-
147
- #### Reading All of the Documents with a Cursor using `find`
148
-
149
- To get all the documents from the collection, we use the `find` method. `find` returns a `Cursor` object, which allows us to iterate over the set of documents that matches our query. The Ruby driver's Cursor implemented Enumerable, which allows us to use `Enumerable#each`, `Enumerable#map}, etc. For instance:
150
-
151
- coll.find.each { |row| puts row.inspect }
152
-
153
- and that should print all 101 documents in the collection. You can take advantage of `Enumerable#to_a`.
154
-
155
- puts coll.find.to_a
156
-
157
- Important note - using `to_a` pulls all of the full result set into memory and is inefficient if you can process by each individual document. To process with more memory efficiency, use the `each` method with a code block for the cursor.
158
-
159
- #### Specific Queries
160
-
161
- We can create a _query_ hash to pass to the `find` method to get a subset of the documents in our collection. To check that our update worked, find the document by id:
162
-
163
- coll.find("_id" => id).to_a
164
-
165
- If we wanted to find the document for which the value of the "i" field is 71, we would do the following:
166
-
167
- coll.find("i" => 71).to_a
168
-
169
- and it should just print just one document:
170
-
171
- {"_id"=>BSON::ObjectId('4f7b20b4e4d30b35c9000049'), "i"=>71}
172
-
173
- #### Sorting Documents in a Collection
174
-
175
- To sort documents, simply use the `sort` method. The method can either take a key or an array of [key, direction] pairs to sort by.
176
-
177
- Direction defaults to ascending order but can be specified as Mongo::ASCENDING, :ascending, or :asc whereas descending order can be specified with Mongo::DESCENDING, :descending, or :desc.
178
-
179
- # Sort in ascending order by :i
180
- coll.find.sort(:i)
181
-
182
- # Sort in descending order by :i
183
- coll.find.sort(:i => :desc)
184
-
185
- #### Counting Documents in a Collection
186
-
187
- Now that we've inserted 101 documents (the 100 we did in the loop, plus the first one), we can check to see if we have them all using the `count` method.
188
-
189
- coll.count
190
-
191
- and it should print `101`.
192
-
193
- #### Getting a Set of Documents With a Query
194
-
195
- We can use the query to get a set of documents from our collection. For example, if we wanted to get all documents where "i" > 50, we could write:
196
-
197
- puts coll.find("i" => {"$gt" => 50}).to_a
198
-
199
- which should print the documents where i > 50. We could also get a range, say 20 < i <= 30:
200
-
201
- puts coll.find("i" => {"$gt" => 20, "$lte" => 30}).to_a
202
-
203
- #### Selecting a Subset of Fields for a Query
204
-
205
- Use the `:fields` option to specify fields to return.
206
-
207
- puts coll.find("_id" => id, :fields => ["name", "type"]).to_a
208
-
209
- #### Querying with Regular Expressions
210
-
211
- Regular expressions can be used to query MongoDB. To find all names that begin with 'M':
212
-
213
- puts coll.find({"name" => /^M/}).to_a
214
-
215
- You can also construct a regular expression dynamically. To match a given search string:
216
-
217
- params = {'search' => 'DB'}
218
- search_string = params['search']
219
-
220
- # Constructor syntax
221
- puts coll.find({"name" => Regexp.new(search_string)}).to_a
222
-
223
- # Literal syntax
224
- puts coll.find({"name" => /#{search_string}/}).to_a
225
-
226
- Although MongoDB isn't vulnerable to anything like SQL-injection, it may be worth checking the search string for anything malicious.
227
-
228
- ### Updating Documents with `update`
229
-
230
- We can update the previous document using the `update` method. There are a couple ways to update a document. We can rewrite it:
231
-
232
- doc["name"] = "MongoDB Ruby"
233
- coll.update({"_id" => id}, doc)
234
-
235
- Or we can use an atomic operator to change a single value:
236
-
237
- coll.update({"_id" => id}, {"$set" => {"name" => "MongoDB Ruby"}})
238
-
239
- Verify the update.
240
-
241
- puts coll.find("_id" => id).to_a
242
-
243
- Read [more about updating documents|Updating].
244
-
245
- ### Deleting Documents with `remove`
246
-
247
- Use the `remove` method to delete documents.
248
-
249
- coll.count
250
- coll.remove("i" => 71)
251
- coll.count
252
- puts coll.find("i" => 71).to_a
253
-
254
- The above shows that the count has been reduced and that the document can no longer be found.
255
-
256
- Without arguments, the `remove` method deletes all documents.
257
-
258
- coll.remove
259
- coll.count
260
-
261
- Please program carefully.
262
-
263
- ## Indexing
264
-
265
- ### Creating An Index
266
-
267
- MongoDB supports indexes, and they are very easy to add on a collection. To create an index, you specify an index name and an array of field names to be indexed, or a single field name. The following creates an ascending index on the "i" field:
268
-
269
- # create_index assumes ascending order; see method docs
270
- # for details
271
- coll.create_index("i")
272
- To specify complex indexes or a descending index you need to use a slightly more complex syntax - the index specifier must be an Array of [field name, direction] pairs. Directions should be specified as Mongo::ASCENDING or Mongo::DESCENDING:
273
-
274
- # Explicit "ascending"
275
- coll.create_index([["i", Mongo::ASCENDING]])
276
-
277
- Use the `explain` method on the cursor to show how MongoDB will run the query.
278
-
279
- coll.find("_id" => id).explain
280
- coll.find("i" => 71).explain
281
- coll.find("type" => "database").explain
282
-
283
- The above shows that the query by `_id` and `i` will use faster indexed BtreeCursor, while the query by `type` will use a slower BasicCursor.
284
-
285
- ### Getting a List of Indexes on a Collection
286
-
287
- You can get a list of the indexes on a collection.
288
-
289
- coll.index_information
290
-
291
- ### Creating and Querying on a Geospatial Index
292
-
293
- First, create the index on a field containing long-lat values:
294
-
295
- people.create_index([["loc", Mongo::GEO2D]])
296
-
297
- Then get a list of the twenty locations nearest to the point 50, 50:
298
-
299
- people.find({"loc" => {"$near" => [50, 50]}}, {:limit => 20}).each do |p|
300
- puts p.inspect
301
- end
302
-
303
- ## Dropping
304
-
305
- ### Drop an Index
306
-
307
- To drop a secondary index, use the `drop_index` method on the collection.
308
-
309
- coll.drop_index("i_1")
310
- coll.index_information
311
-
312
- The dropped index is no longer listed.
313
-
314
- ### Drop All Indexes
315
-
316
- To drop all secondary indexes, use the `drop_indexes` method on the collection.
317
-
318
- coll.drop_indexes
319
- coll.index_information
320
-
321
- Only the primary index "_id_" is listed.
322
-
323
- ### Drop a Collection
324
-
325
- To drop a collection, use the `drop` method on the collection.
326
-
327
- coll.drop
328
- db.collection_names
329
-
330
- The dropped collection is no longer listed. The `drop_collection` method can be used on the database as an alternative.
331
-
332
- db.drop_collection("testCollection")
333
-
334
- ### Drop a Database
335
-
336
- To drop a database, use the `drop_database` method on the connection.
337
-
338
- connection.drop_database("mydb")
339
- connection.database_names
340
-
341
- The dropped database is no longer listed.
342
-
343
- ## Database Administration
344
-
345
- A database can have one of three profiling levels: off (:off), slow queries only (:slow_only), or all (:all). To see the database level:
346
-
347
- puts db.profiling_level # => off (the symbol :off printed as a string)
348
- db.profiling_level = :slow_only
349
-
350
- Validating a collection will return an interesting hash if all is well or raise an exception if there is a problem.
351
- p db.validate_collection('coll_name')
352
-
353
- ## See Also
354
-
355
- * [MongoDB Koans](http://github.com/chicagoruby/MongoDB_Koans) A path to MongoDB enlightenment via the Ruby driver.
356
- * [MongoDB Manual](http://www.mongodb.org/display/DOCS/Developer+Zone)