mongo 1.0 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. data/LICENSE.txt +1 -13
  2. data/{README.rdoc → README.md} +129 -149
  3. data/Rakefile +94 -58
  4. data/bin/mongo_console +21 -0
  5. data/docs/1.0_UPGRADE.md +21 -0
  6. data/docs/CREDITS.md +123 -0
  7. data/docs/FAQ.md +112 -0
  8. data/docs/GridFS.md +158 -0
  9. data/docs/HISTORY.md +185 -0
  10. data/docs/REPLICA_SETS.md +75 -0
  11. data/docs/TUTORIAL.md +247 -0
  12. data/docs/WRITE_CONCERN.md +28 -0
  13. data/lib/mongo/collection.rb +225 -105
  14. data/lib/mongo/connection.rb +374 -315
  15. data/lib/mongo/cursor.rb +122 -77
  16. data/lib/mongo/db.rb +109 -85
  17. data/lib/mongo/exceptions.rb +6 -0
  18. data/lib/mongo/gridfs/grid.rb +19 -11
  19. data/lib/mongo/gridfs/grid_ext.rb +36 -9
  20. data/lib/mongo/gridfs/grid_file_system.rb +15 -9
  21. data/lib/mongo/gridfs/grid_io.rb +49 -16
  22. data/lib/mongo/gridfs/grid_io_fix.rb +38 -0
  23. data/lib/mongo/repl_set_connection.rb +290 -0
  24. data/lib/mongo/util/conversions.rb +3 -1
  25. data/lib/mongo/util/core_ext.rb +17 -4
  26. data/lib/mongo/util/pool.rb +125 -0
  27. data/lib/mongo/util/server_version.rb +2 -0
  28. data/lib/mongo/util/support.rb +12 -0
  29. data/lib/mongo/util/uri_parser.rb +71 -0
  30. data/lib/mongo.rb +23 -7
  31. data/{mongo-ruby-driver.gemspec → mongo.gemspec} +9 -7
  32. data/test/auxillary/1.4_features.rb +2 -2
  33. data/test/auxillary/authentication_test.rb +1 -1
  34. data/test/auxillary/autoreconnect_test.rb +1 -1
  35. data/test/{slave_connection_test.rb → auxillary/slave_connection_test.rb} +6 -6
  36. data/test/bson/binary_test.rb +15 -0
  37. data/test/bson/bson_test.rb +537 -0
  38. data/test/bson/byte_buffer_test.rb +190 -0
  39. data/test/bson/hash_with_indifferent_access_test.rb +38 -0
  40. data/test/bson/json_test.rb +17 -0
  41. data/test/bson/object_id_test.rb +141 -0
  42. data/test/bson/ordered_hash_test.rb +197 -0
  43. data/test/collection_test.rb +195 -15
  44. data/test/connection_test.rb +93 -56
  45. data/test/conversions_test.rb +1 -1
  46. data/test/cursor_fail_test.rb +75 -0
  47. data/test/cursor_message_test.rb +43 -0
  48. data/test/cursor_test.rb +93 -32
  49. data/test/db_api_test.rb +28 -55
  50. data/test/db_connection_test.rb +2 -3
  51. data/test/db_test.rb +45 -40
  52. data/test/grid_file_system_test.rb +14 -6
  53. data/test/grid_io_test.rb +36 -7
  54. data/test/grid_test.rb +54 -10
  55. data/test/replica_sets/connect_test.rb +84 -0
  56. data/test/replica_sets/count_test.rb +35 -0
  57. data/test/{replica → replica_sets}/insert_test.rb +17 -14
  58. data/test/replica_sets/pooled_insert_test.rb +55 -0
  59. data/test/replica_sets/query_secondaries.rb +80 -0
  60. data/test/replica_sets/query_test.rb +41 -0
  61. data/test/replica_sets/replication_ack_test.rb +64 -0
  62. data/test/replica_sets/rs_test_helper.rb +29 -0
  63. data/test/safe_test.rb +68 -0
  64. data/test/support/hash_with_indifferent_access.rb +199 -0
  65. data/test/support/keys.rb +45 -0
  66. data/test/support_test.rb +19 -0
  67. data/test/test_helper.rb +53 -15
  68. data/test/threading/{test_threading_large_pool.rb → threading_with_large_pool_test.rb} +2 -2
  69. data/test/threading_test.rb +2 -2
  70. data/test/tools/repl_set_manager.rb +241 -0
  71. data/test/tools/test.rb +13 -0
  72. data/test/unit/collection_test.rb +70 -7
  73. data/test/unit/connection_test.rb +18 -39
  74. data/test/unit/cursor_test.rb +7 -8
  75. data/test/unit/db_test.rb +14 -17
  76. data/test/unit/grid_test.rb +49 -0
  77. data/test/unit/pool_test.rb +9 -0
  78. data/test/unit/repl_set_connection_test.rb +82 -0
  79. data/test/unit/safe_test.rb +125 -0
  80. metadata +132 -51
  81. data/bin/bson_benchmark.rb +0 -59
  82. data/bin/fail_if_no_c.rb +0 -11
  83. data/examples/admin.rb +0 -43
  84. data/examples/capped.rb +0 -22
  85. data/examples/cursor.rb +0 -48
  86. data/examples/gridfs.rb +0 -44
  87. data/examples/index_test.rb +0 -126
  88. data/examples/info.rb +0 -31
  89. data/examples/queries.rb +0 -70
  90. data/examples/simple.rb +0 -24
  91. data/examples/strict.rb +0 -35
  92. data/examples/types.rb +0 -36
  93. data/test/replica/count_test.rb +0 -34
  94. data/test/replica/pooled_insert_test.rb +0 -54
  95. data/test/replica/query_test.rb +0 -39
data/docs/HISTORY.md ADDED
@@ -0,0 +1,185 @@
1
+ # MongoDB Ruby Driver History
2
+
3
+ ### 1.1.5
4
+ 2010-12-15
5
+
6
+ * ReplSetConnection class. This must be used for replica set connections from
7
+ now on. You can still use Connection.multi, but that method has been deprecated.
8
+ * Automated replica set tests. rake test:rs
9
+ * Check that request and response ids match.
10
+ * Several bug fixes. See the commit history for details.
11
+
12
+ ### 1.1.4
13
+ 2010-11-30
14
+
15
+ * Important connection failure fix.
16
+ * ObjectId#to_s optimization (David Cuadrado).
17
+
18
+ ### 1.1.3
19
+ 2010-11-29
20
+
21
+ * Distributed reads for replica set secondaries. See /docs/examples/replica_set.rb and
22
+ http://api.mongodb.org/ruby/current/file.REPLICA_SETS.html for details.
23
+ * Note: when connecting to a replica set, you must use Connection#multi.
24
+ * Cursor#count takes optional skip and limit
25
+ * Collection#ensure_index for caching index creation calls
26
+ * Collection#update and Collection#remove now return error object when using safe mode
27
+ * Important fix for int/long serialization on bug introduced in 1.0.9
28
+ * Numerous tweaks and bug fixes.
29
+
30
+ ### 1.1.2
31
+ 2010-11-4
32
+
33
+ * Two critical fixes to automated failover and replica sets.
34
+ * Bug passing :timeout to Cursor.
35
+ * Permit safe mode specification on Connection, Collection, and DB levels.
36
+ * Specify replica set name on connect to verify connection to the right set.
37
+ * Misc. reorganization of project and docs.
38
+
39
+ ### 1.1.1
40
+ 2010-10-14
41
+
42
+ * Several critical JRuby bug fixes
43
+ * Fixes for JRuby in 1.9 mode
44
+ * Check keys and move id only when necessary for JRuby encoder
45
+
46
+ ## 1.1
47
+ 2010-10-4
48
+
49
+ * Official JRuby support via Java extensons for BSON (beta)
50
+ * Connection#lock! and Connection#unlock! for easy fsync lock
51
+ * Note: BSON::Code is no longer a subclass of String.
52
+
53
+ ### 1.0.9
54
+ 2010-9-20
55
+
56
+ * Significant performance improvements (with a lot of help from Hongli Lai)
57
+
58
+ ### 1.0.8
59
+ 2010-8-27
60
+
61
+ * Cursor#rewind! and more consistent Cursor Enumberable behavior
62
+ * Deprecated ObjectID for ObjectId
63
+ * Numerous minor bug fixes.
64
+
65
+ ### 1.0.7
66
+ 2010-8-4
67
+
68
+ * A few minor test/doc fixes.
69
+ * Better tests for replica sets and replication acknowledgment.
70
+ * Deprecated DB#error and DB#last_status
71
+
72
+ ### 1.0.6
73
+ 2010-7-26
74
+
75
+ * Replica set support.
76
+ * Collection#map_reduce bug fix.
77
+
78
+ ### 1.0.5
79
+ 2010-7-13
80
+
81
+ * Fix for bug introduced in 1.0.4.
82
+
83
+ ### 1.0.4
84
+ 2010-7-13
85
+
86
+ * Removed deprecated
87
+ * Cursor admin option
88
+ * DB#query
89
+ * DB#create_index (use Collection#create_index)
90
+ * DB#command only takes hash options now
91
+ * j2bson executable (neomantra)
92
+ * Fixed bson_ext compilation on Solaris (slyphon)
93
+ * System JS helpers (neovintage)
94
+ * Use one mutex per thread on pooled connections (cremes)
95
+ * Check for CursorNotFound response flag
96
+ * MapReduce can return raw command output using :raw
97
+ * BSON::OrderedHash equality with other Ruby hashes (Ryan Angilly)
98
+ * Fix for broken Socket.send with large payloads (Frédéric De Jaeger)
99
+ * Lots of minor improvements. See commmits.
100
+
101
+ ### 1.0.3
102
+ 2010-6-15
103
+
104
+ * Optimiztion for BSON::OrderedHash
105
+ * Some important fixes.
106
+
107
+ ### 1.0.2
108
+ 2010-6-5
109
+
110
+ This is a minor release for fixing an incompatibility with MongoDB v1.5.2
111
+
112
+ * Fix for boolean response on commands for core server v1.5.2
113
+ * BSON.read_bson_document and b2json executable (neomantra)
114
+ * BSON::ObjectID() shortcut for BSON::ObjectID.from_string (tmm1)
115
+ * Various bug fixes.
116
+
117
+ ### 1.0.1
118
+ 2010-5-7
119
+
120
+ * set Encoding.default_internal
121
+ * DEPRECATE JavaScript string on Collection#find. You now must specify $where explicitly.
122
+ * Added Grid#exist? and GridFileSystem#exist?
123
+ * Support for replication acknowledgment
124
+ * Support for $slice
125
+ * Namespaced OrderedHash under BSON (sleverbor)
126
+
127
+ ## 1.0
128
+ 2010-4-29
129
+ Note: if upgrading from versions prior to 0.20, be sure to upgrade
130
+ to 0.20 before upgrading to 1.0.
131
+
132
+ * Inspected ObjectID is represented in MongoDB extended json format.
133
+ * Support for tailable cursors.
134
+ * Configurable query response batch size (thx. to Aman Gupta)
135
+
136
+ * bson_ext installs on early release of Ruby 1.8.5 (dfitzgibbon)
137
+ * Deprecated DB#create_index. Use Collection#create_index index.
138
+ * Removed deprecated Grid#put syntax; no longer requires a filename.
139
+
140
+ ### 0.20.1
141
+ 2010-4-7
142
+
143
+ * Added bson gem dependency.
144
+
145
+ ### 0.20
146
+ 2010-4-7
147
+
148
+ If upgrading from a previous version of the Ruby driver, please read these notes carefully,
149
+ along with the 0.20_UPGRADE doc.
150
+
151
+ * Support for new commands:
152
+ * Collection#find_and_modify
153
+ * Collection#stats
154
+ * DB#stats
155
+ * Query :fields options allows for values of 0 to exclude fields (houdini, railsjedi).
156
+ * GridFS
157
+ * Option to delete old versions of GridFileSystem entries.
158
+ * Filename is now optional for Grid#put.
159
+ * Option to write arbitrary attributes to a file: @grid.put(@data, :favorite_phrase => "blimey!")
160
+ * Indexes created on the chunks collection are now unique. If you have an existing chunks collection,
161
+ you may want to remove
162
+ * Removed the following deprecated items:
163
+ * GridStore class
164
+ * RegexpOfHolding class
165
+ * Paired connections must now be initialized with Connection.paired
166
+
167
+ * BSON-related code extracted into two separate gems: bson and bson_ext (thx to Chuck Remes).
168
+ * mongo_ext no longer exists.
169
+ * BSON::Binary constructor can now take a string, which will be packed into an array.
170
+ * Exception class adjustments:
171
+ * Mongo::InvalidObjectID moved to BSON::InvalidObjectID
172
+ * Mongo::InvalidDocument moved to BSON::InvalidDocument
173
+ * Mongo::InvalidStringEncoding moved to BSON::InvalidStringEncoding
174
+ * Mongo::InvalidName replaced by Mongo::InvalidNSName and BSON::InvalidKeyName
175
+ * BSON types are now namespaced under the BSON module. These types include:
176
+ * Binary
177
+ * ObjectID
178
+ * Code
179
+ * DBRef
180
+ * MinKey and MaxKey
181
+ * Extensions compile on Rubinius (Chuck Remes).
182
+
183
+ ## Prior to 0.20
184
+
185
+ See git revisions.
@@ -0,0 +1,75 @@
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:
10
+
11
+ @connection = ReplSetConnection.new(['n1.mydb.net', 27017], ['n2.mydb.net', 27017], ['n3.mydb.net', 27017])
12
+
13
+ The driver will attempt to connect to a master node and, when found, will replace all seed nodes with known members of the replica set.
14
+
15
+ ### Read slaves
16
+
17
+ If you want to read from a seconday node, you can pass :read_secondary => true to ReplSetConnection#new.
18
+
19
+ @connection = ReplSetConnection.new(['n1.mydb.net', 27017], ['n2.mydb.net', 27017], ['n3.mydb.net', 27017],
20
+ :read_secondary => true)
21
+
22
+ 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.
23
+
24
+ ### Connection Failures
25
+
26
+ Imagine that either the master node or one of the read nodes goes offline. How will the driver respond?
27
+
28
+ 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.
29
+
30
+ 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.
31
+
32
+ The driver will essentially cycle through all known seed addresses until a node identifies itself as master.
33
+
34
+ ### Recovery
35
+
36
+ Driver users may wish to wrap their database calls with failure recovery code. Here's one possibility, which will attempt to connection
37
+ every half second and time out after thirty seconds.
38
+
39
+ # Ensure retry upon failure
40
+ def rescue_connection_failure(max_retries=60)
41
+ success = false
42
+ retries = 0
43
+ while !success
44
+ begin
45
+ yield
46
+ success = true
47
+ rescue Mongo::ConnectionFailure => ex
48
+ retries += 1
49
+ raise ex if retries >= max_retries
50
+ sleep(0.5)
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ # Wrapping a call to #count()
57
+ rescue_connection_failure do
58
+ @db.collection('users').count()
59
+ end
60
+
61
+ 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.
62
+
63
+ ### Testing
64
+
65
+ 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:
66
+
67
+ rake test:rs
68
+
69
+ The suite will set up a five-node replica set by itself and ensure that driver behaves correctly even in the face
70
+ of individual node failures. Node that the `mongod` executable must be in the search path for this to work.
71
+
72
+ ### Further Reading
73
+
74
+ * [Replica Sets](http://www.mongodb.org/display/DOCS/Replica+Set+Configuration)
75
+ * [Replics Set Configuration](http://www.mongodb.org/display/DOCS/Replica+Set+Configuration)
data/docs/TUTORIAL.md ADDED
@@ -0,0 +1,247 @@
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
+ gem update --system
13
+ Next, install the mongo rubygem:
14
+ gem install mongo
15
+
16
+ The required `bson` gem will be installed automatically.
17
+
18
+ For optimum performance, install the bson_ext gem:
19
+
20
+ gem install bson_ext
21
+
22
+ 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.
23
+
24
+ ## Getting started
25
+
26
+ #### Using the gem
27
+
28
+ All of the code here assumes that you have already executed the following Ruby code:
29
+
30
+ require 'rubygems' # not necessary for Ruby 1.9
31
+ require 'mongo'
32
+
33
+ #### Making a Connection
34
+
35
+ An `Mongo::Connection` instance represents a connection to MongoDB. 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.
36
+
37
+ You can optionally specify the MongoDB server address and port when connecting. The following example shows three ways to connect to the database "mydb" on the local machine:
38
+
39
+ db = Mongo::Connection.new.db("mydb")
40
+ db = Mongo::Connection.new("localhost").db("mydb")
41
+ db = Mongo::Connection.new("localhost", 27017).db("mydb")
42
+
43
+ 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.
44
+
45
+ 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).
46
+
47
+ #### Listing All Databases
48
+
49
+ connection = Mongo::Connection.new # (optional host/port args)
50
+ connection.database_names.each { |name| puts name }
51
+ connection.database_info.each { |info| puts info.inspect}
52
+
53
+ #### Dropping a Database
54
+ connection.drop_database('database_name')
55
+
56
+ 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:
57
+
58
+ auth = db.authenticate(my_user_name, my_password)
59
+
60
+ 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.
61
+
62
+ #### Getting a List Of Collections
63
+
64
+ Each database has zero or more collections. You can retrieve a list of them from the db (and print out any that are there):
65
+
66
+ db.collection_names.each { |name| puts name }
67
+
68
+ and assuming that there are two collections, name and address, in the database, you would see
69
+
70
+ name
71
+ address
72
+
73
+ as the output.
74
+
75
+ #### Getting a Collection
76
+
77
+ You can get a collection to use using the `collection` method:
78
+ coll = db.collection("testCollection")
79
+ This is aliased to the \[\] method:
80
+ coll = db["testCollection"]
81
+
82
+ Once you have this collection object, you can now do things like insert data, query for data, etc.
83
+
84
+ #### Inserting a Document
85
+
86
+ Once you have the collection object, you can insert documents into the collection. For example, lets make a little document that in JSON would be represented as
87
+
88
+ {
89
+ "name" : "MongoDB",
90
+ "type" : "database",
91
+ "count" : 1,
92
+ "info" : {
93
+ x : 203,
94
+ y : 102
95
+ }
96
+ }
97
+
98
+ 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.
99
+
100
+ doc = {"name" => "MongoDB", "type" => "database", "count" => 1,
101
+ "info" => {"x" => 203, "y" => '102'`
102
+ coll.insert(doc)
103
+
104
+ #### Updating a Document
105
+
106
+ We can update the previous document using the `update` method. There are a couple ways to update a document. We can rewrite it:
107
+
108
+ doc["name"] = "MongoDB Ruby"
109
+ coll.update({"_id" => doc["_id"]}, doc)
110
+
111
+ Or we can use an atomic operator to change a single value:
112
+
113
+ coll.update({"_id" => doc["_id"]}, {"$set" => {"name" => "MongoDB Ruby"`)
114
+
115
+ Read [more about updating documents|Updating].
116
+
117
+ #### Finding the First Document In a Collection using `find_one()`
118
+
119
+ To show that the document we inserted in the previous step is there, we can do a simple `find_one()` operation to get the first document in the collection. This method returns a single document (rather than the `Cursor` that the `find()` operation returns).
120
+
121
+ my_doc = coll.find_one()
122
+ puts my_doc.inspect
123
+
124
+ and you should see:
125
+
126
+ {"_id"=>#<BSON::ObjectID:0x118576c ...>, "name"=>"MongoDB",
127
+ "info"=>{"x"=>203, "y"=>102}, "type"=>"database", "count"=>1}
128
+
129
+ Note the `\_id` element has been added automatically by MongoDB to your document.
130
+
131
+ #### Adding Multiple Documents
132
+
133
+ To demonstrate some more interesting queries, let's add multiple simple documents to the collection. These documents will have the following form:
134
+ {
135
+ "i" : value
136
+ }
137
+
138
+ Here's how to insert them:
139
+
140
+ 100.times { |i| coll.insert("i" => i) }
141
+
142
+ 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".
143
+
144
+ #### Counting Documents in a Collection
145
+
146
+ 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.
147
+
148
+ puts coll.count()
149
+
150
+ and it should print `101`.
151
+
152
+ #### Using a Cursor to get all of the Documents
153
+
154
+ 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:
155
+
156
+ coll.find().each { |row| puts row.inspect }
157
+
158
+ and that should print all 101 documents in the collection.
159
+
160
+ #### Getting a Single Document with a Query
161
+
162
+ We can create a _query_ hash to pass to the `find()` method to get a subset of the documents in our collection. For example, if we wanted to find the document for which the value of the "i" field is 71, we would do the following ;
163
+
164
+ coll.find("i" => 71).each { |row| puts row.inspect }
165
+
166
+ and it should just print just one document:
167
+
168
+ {"_id"=>#<BSON::ObjectID:0x117de90 ...>, "i"=>71}
169
+
170
+ #### Getting a Set of Documents With a Query
171
+
172
+ 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:
173
+
174
+ coll.find("i" => {"$gt" => 50}).each { |row| puts row }
175
+
176
+ which should print the documents where i > 50. We could also get a range, say 20 < i <= 30:
177
+
178
+ coll.find("i" => {"$gt" => 20, "$lte" => 30}).each { |row| puts row }
179
+
180
+ #### Selecting a subset of fields for a query
181
+
182
+ Use the `:fields` option. If you just want fields "a" and "b":
183
+
184
+ coll.find("i" => {"$gt" => 50}, :fields => ["a", "b"]).each { |row| puts row }
185
+
186
+ #### Querying with Regular Expressions
187
+
188
+ Regular expressions can be used to query MongoDB. To find all names that begin with 'a':
189
+
190
+ coll.find({"name" => /^a/})
191
+
192
+ You can also construct a regular expression dynamically. To match a given search string:
193
+
194
+ search_string = params['search']
195
+
196
+ # Constructor syntax
197
+ coll.find({"name" => Regexp.new(search_string)})
198
+
199
+ # Literal syntax
200
+ coll.find({"name" => /#{search_string}/})
201
+
202
+ Although MongoDB isn't vulnerable to anything like SQL-injection, it may be worth checking the search string for anything malicious.
203
+
204
+ ## Indexing
205
+
206
+ #### Creating An Index
207
+
208
+ 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:
209
+
210
+ # create_index assumes ascending order; see method docs
211
+ # for details
212
+ coll.create_index("i")
213
+ 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:
214
+
215
+ # Explicit "ascending"
216
+ coll.create_index([["i", Mongo::ASCENDING]])
217
+
218
+ #### Creating and querying on a geospatial index
219
+
220
+ First, create the index on a field containing long-lat values:
221
+
222
+ people.create_index([["loc", Mongo::GEO2D]])
223
+
224
+ Then get a list of the twenty locations nearest to the point 50, 50:
225
+
226
+ people.find({"loc" => {"$near" => [50, 50]}}, {:limit => 20}).each do |p|
227
+ puts p.inspect
228
+ end
229
+
230
+ #### Getting a List of Indexes on a Collection
231
+
232
+ You can get a list of the indexes on a collection using `coll.index_information()`.
233
+
234
+ ## Database Administration
235
+
236
+ A database can have one of three profiling levels: off (:off), slow queries only (:slow_only), or all (:all). To see the database level:
237
+
238
+ puts db.profiling_level # => off (the symbol :off printed as a string)
239
+ db.profiling_level = :slow_only
240
+
241
+ Validating a collection will return an interesting hash if all is well or raise an exception if there is a problem.
242
+ p db.validate_collection('coll_name')
243
+
244
+ ## See Also
245
+
246
+ * [MongoDB Koans](http://github.com/chicagoruby/MongoDB_Koans) A path to MongoDB enlightenment via the Ruby driver.
247
+ * [MongoDB Manual](http://www.mongodb.org/display/DOCS/Developer+Zone)
@@ -0,0 +1,28 @@
1
+ # Write Concern in Ruby
2
+
3
+ ## Setting the write concern
4
+
5
+ Write concern is set using the `:safe` option. There are several possible options:
6
+
7
+ @collection.save({:doc => 'foo'}, :safe => true)
8
+ @collection.save({:doc => 'foo'}, :safe => {:w => 2})
9
+ @collection.save({:doc => 'foo'}, :safe => {:w => 2, :wtimeout => 200})
10
+ @collection.save({:doc => 'foo'}, :safe => {:w => 2, :wtimeout => 200, :fsync => true})
11
+
12
+ The first, `true`, simply indicates that we should request a response from the server to ensure that to errors have occurred. The second, `{:w => 2}`forces the server to wait until at least two servers have recorded the write. The third does the same but will time out if the replication can't be completed in 200 milliseconds. The fourth forces an fsync on each server being written to (note: this option is rarely necessary and will have a dramaticly negative effect on performance).
13
+
14
+ ## Write concern inheritance
15
+
16
+ The Ruby driver allows you to set write concern on each of four levels: the connection, database, collection, and write operation.
17
+ Objects will inherit the default write concern from their parents. Thus, if you set a write concern of `{:w => 1}` when creating
18
+ a new connection, then all databases and collections created from that connection will inherit the same setting. See this code example:
19
+
20
+ @con = Mongo::Connection.new('localhost', 27017, :safe => {:w => 2})
21
+ @db = @con['test']
22
+ @collection = @db['foo']
23
+ @collection.save({:name => 'foo'})
24
+
25
+ @collection.save({:name => 'bar'}, :safe => false)
26
+
27
+ Here, the first call to Collection#save will use the inherited write concern, `{:w => 2}`. But notice that the second call
28
+ to Collection#save overrides this setting.