mongo 1.6.1 → 1.6.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +17 -16
- data/Rakefile +30 -24
- data/docs/HISTORY.md +10 -0
- data/docs/RELEASES.md +7 -0
- data/docs/REPLICA_SETS.md +2 -2
- data/docs/TUTORIAL.md +181 -84
- data/lib/mongo.rb +0 -3
- data/lib/mongo/collection.rb +1 -1
- data/lib/mongo/connection.rb +28 -20
- data/lib/mongo/db.rb +5 -3
- data/lib/mongo/exceptions.rb +1 -1
- data/lib/mongo/gridfs/grid_file_system.rb +1 -1
- data/lib/mongo/networking.rb +18 -18
- data/lib/mongo/repl_set_connection.rb +24 -3
- data/lib/mongo/util/node.rb +6 -16
- data/lib/mongo/util/pool.rb +8 -11
- data/lib/mongo/util/ssl_socket.rb +34 -12
- data/lib/mongo/util/tcp_socket.rb +92 -3
- data/lib/mongo/util/uri_parser.rb +2 -2
- data/lib/mongo/version.rb +1 -1
- data/test/auxillary/repl_set_auth_test.rb +19 -5
- data/test/bson/bson_test.rb +23 -21
- data/test/bson/json_test.rb +1 -1
- data/test/collection_test.rb +14 -4
- data/test/connection_test.rb +14 -11
- data/test/cursor_test.rb +4 -4
- data/test/grid_file_system_test.rb +3 -1
- data/test/grid_io_test.rb +2 -2
- data/test/grid_test.rb +13 -6
- data/test/pool_test.rb +0 -2
- data/test/replica_sets/basic_test.rb +1 -1
- data/test/replica_sets/complex_connect_test.rb +5 -4
- data/test/replica_sets/connect_test.rb +14 -6
- data/test/replica_sets/pooled_insert_test.rb +1 -1
- data/test/replica_sets/query_test.rb +2 -2
- data/test/replica_sets/read_preference_test.rb +1 -2
- data/test/replica_sets/refresh_test.rb +4 -2
- data/test/replica_sets/refresh_with_threads_test.rb +7 -13
- data/test/replica_sets/rs_test_helper.rb +1 -1
- data/test/test_helper.rb +6 -4
- data/test/threading/threading_with_large_pool_test.rb +1 -1
- data/test/threading_test.rb +2 -2
- data/test/timeout_test.rb +40 -0
- data/test/tools/repl_set_manager.rb +9 -8
- data/test/unit/connection_test.rb +6 -7
- data/test/unit/node_test.rb +1 -0
- data/test/unit/pool_manager_test.rb +2 -1
- data/test/uri_test.rb +1 -2
- metadata +13 -6
data/README.md
CHANGED
@@ -62,7 +62,7 @@ And for a significant performance boost, you'll want to install the C extensions
|
|
62
62
|
$ gem install bson_ext
|
63
63
|
|
64
64
|
Note that bson_ext isn't used with JRuby. Instead, some native Java extensions are bundled with the bson gem.
|
65
|
-
If you ever need to modify these
|
65
|
+
If you ever need to modify these extensions, you can recompile with the following rake task:
|
66
66
|
|
67
67
|
$ rake build:java
|
68
68
|
|
@@ -103,7 +103,7 @@ See also the test code, especially test/test_db_api.rb.
|
|
103
103
|
|
104
104
|
The Ruby driver include two abstractions for storing large files: Grid and GridFileSystem.
|
105
105
|
The Grid class is a Ruby implementation of MongoDB's GridFS file storage
|
106
|
-
specification. GridFileSystem is
|
106
|
+
specification. GridFileSystem is essentially the same, but provides a more filesystem-like API
|
107
107
|
and assumes that filenames are unique.
|
108
108
|
|
109
109
|
An instance of both classes represents an individual file store. See the API reference
|
@@ -264,9 +264,22 @@ If implementing higher-level timeouts, using tools like `Rack::Timeout`, it's ve
|
|
264
264
|
to call `Mongo::Connection#close` to prevent the subsequent operation from receiving the previous
|
265
265
|
request.
|
266
266
|
|
267
|
+
### Test-Unit, Shoulda, and Mocha
|
268
|
+
|
269
|
+
Running the test suite requires test-unit, shoulda, and mocha. You can install them as follows:
|
270
|
+
|
271
|
+
$ gem install test-unit
|
272
|
+
$ gem install shoulda
|
273
|
+
$ gem install mocha
|
274
|
+
|
275
|
+
The tests assume that the Mongo database is running on the default port. You
|
276
|
+
can override the default host (localhost) and port (Connection::DEFAULT_PORT) by
|
277
|
+
using the environment variables MONGO_RUBY_DRIVER_HOST and
|
278
|
+
MONGO_RUBY_DRIVER_PORT.
|
279
|
+
|
267
280
|
# Testing
|
268
281
|
|
269
|
-
If you have the source code, you can run the tests.
|
282
|
+
If you have the source code, you can run the tests. Skip this test with the C extension if you're running JRuby.
|
270
283
|
|
271
284
|
$ rake test:c
|
272
285
|
|
@@ -279,7 +292,7 @@ These will run both unit and functional tests. To run these tests alone:
|
|
279
292
|
$ rake test:unit
|
280
293
|
$ rake test:functional
|
281
294
|
|
282
|
-
To run any individual rake tasks with the C extension enabled, just pass C_EXT=true to the task:
|
295
|
+
To run any individual rake tasks with the C extension enabled, just pass C_EXT=true to the task (don't do this with JRuby):
|
283
296
|
|
284
297
|
$ rake test:unit C_EXT=true
|
285
298
|
|
@@ -287,18 +300,6 @@ If you want to test replica set, you can run the following task:
|
|
287
300
|
|
288
301
|
$ rake test:rs
|
289
302
|
|
290
|
-
### Shoulda and Mocha
|
291
|
-
|
292
|
-
Running the test suite requires shoulda and mocha. You can install them as follows:
|
293
|
-
|
294
|
-
$ gem install shoulda
|
295
|
-
$ gem install mocha
|
296
|
-
|
297
|
-
The tests assume that the Mongo database is running on the default port. You
|
298
|
-
can override the default host (localhost) and port (Connection::DEFAULT_PORT) by
|
299
|
-
using the environment variables MONGO_RUBY_DRIVER_HOST and
|
300
|
-
MONGO_RUBY_DRIVER_PORT.
|
301
|
-
|
302
303
|
# Documentation
|
303
304
|
|
304
305
|
This documentation is available online at [http://api.mongodb.org/ruby](http://api.mongodb.org/ruby). You can
|
data/Rakefile
CHANGED
@@ -160,7 +160,7 @@ end
|
|
160
160
|
|
161
161
|
desc "Generate YARD documentation"
|
162
162
|
task :ydoc do
|
163
|
-
require 'mongo'
|
163
|
+
require './lib/mongo/version.rb'
|
164
164
|
out = File.join('ydoc', Mongo::VERSION)
|
165
165
|
FileUtils.rm_rf('ydoc')
|
166
166
|
system "yardoc lib/**/*.rb lib/mongo/**/*.rb lib/bson/**/*.rb -e ./yard/yard_ext.rb -p yard/templates -o #{out} --title MongoRuby-#{Mongo::VERSION} --files docs/TUTORIAL.md,docs/GridFS.md,docs/FAQ.md,docs/REPLICA_SETS.md,docs/WRITE_CONCERN.md,docs/READ_PREFERENCE.md,docs/HISTORY.md,docs/CREDITS.md,docs/RELEASES.md,docs/CREDITS.md,docs/TAILABLE_CURSORS.md"
|
@@ -188,7 +188,6 @@ namespace :jenkins do
|
|
188
188
|
end
|
189
189
|
|
190
190
|
namespace :gem do
|
191
|
-
|
192
191
|
desc "Install the gem locally"
|
193
192
|
task :install do
|
194
193
|
`gem build bson.gemspec`
|
@@ -212,17 +211,6 @@ namespace :gem do
|
|
212
211
|
`gem install --no-rdoc --no-ri bson_ext-*.gem`
|
213
212
|
`rm bson_ext-*.gem`
|
214
213
|
end
|
215
|
-
|
216
|
-
desc "Build all gems"
|
217
|
-
task :build_all do
|
218
|
-
`rm *.gem`
|
219
|
-
`gem build mongo.gemspec`
|
220
|
-
`gem build bson.gemspec`
|
221
|
-
`gem build bson.java.gemspec`
|
222
|
-
`gem build bson_ext.gemspec`
|
223
|
-
puts `ls *.gem`
|
224
|
-
end
|
225
|
-
|
226
214
|
end
|
227
215
|
|
228
216
|
namespace :ci do
|
@@ -271,6 +259,7 @@ end
|
|
271
259
|
|
272
260
|
def change_version(new_version)
|
273
261
|
version = current_version
|
262
|
+
puts "Changing version from #{version} to #{new_version}"
|
274
263
|
VERSION_FILES.each do |filename|
|
275
264
|
f = File.open(filename)
|
276
265
|
str = f.read
|
@@ -283,30 +272,47 @@ def change_version(new_version)
|
|
283
272
|
end
|
284
273
|
|
285
274
|
namespace :deploy do
|
286
|
-
|
287
|
-
|
288
|
-
|
275
|
+
desc "Change version to new release"
|
276
|
+
task :change_version, [:version] do |t, args|
|
277
|
+
check_version(args[:version])
|
289
278
|
change_version(args[:version])
|
290
279
|
end
|
291
280
|
|
292
|
-
|
281
|
+
desc "Add version files, commit, tag release"
|
282
|
+
task :git_prepare do |t, args|
|
293
283
|
g = Git.open(Dir.getwd())
|
294
|
-
version =
|
295
|
-
|
296
|
-
g.add(
|
284
|
+
version = current_version
|
285
|
+
to_commit = VERSION_FILES << 'docs/HISTORY.md'
|
286
|
+
g.add(to_commit)
|
297
287
|
g.commit "RELEASE #{version}"
|
298
288
|
g.add_tag("#{version}")
|
299
289
|
end
|
300
290
|
|
291
|
+
desc "Push release to github"
|
301
292
|
task :git_push do
|
302
293
|
g = Git.open(Dir.getwd())
|
303
294
|
g.push
|
304
295
|
end
|
305
296
|
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
297
|
+
desc "Build all gems"
|
298
|
+
task :gem_build do
|
299
|
+
`rm *.gem`
|
300
|
+
`gem build mongo.gemspec`
|
301
|
+
`gem build bson.gemspec`
|
302
|
+
`gem build bson.java.gemspec`
|
303
|
+
`gem build bson_ext.gemspec`
|
304
|
+
puts `ls *.gem`
|
305
|
+
end
|
306
|
+
|
307
|
+
desc "Push all gems to RubyGems"
|
308
|
+
task :gem_push do |t, args|
|
309
|
+
check_gem_list_existence(current_version)
|
310
|
+
gem_list.each do |gem|
|
311
|
+
puts "Push #{gem} to RubyGems? (y/N)"
|
312
|
+
if gets.chomp! == 'y'
|
313
|
+
system "gem push #{gem}"
|
314
|
+
end
|
315
|
+
end
|
310
316
|
end
|
311
317
|
end
|
312
318
|
|
data/docs/HISTORY.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# MongoDB Ruby Driver History
|
2
2
|
|
3
|
+
### 1.6.2
|
4
|
+
2012-04-05
|
5
|
+
|
6
|
+
* Implements socket timeouts via non-blocking IO instead of Timeout module
|
7
|
+
which should greately increase performance in highly threaded applications
|
8
|
+
* Added ability to authentication via secondary if primary node unavailable
|
9
|
+
* Replica set refresh interval now enforces a lower bound of 60 seconds
|
10
|
+
* Added documentation for dropping indexes, collections, databases
|
11
|
+
* Test output cleanup (...)s unless failure occurs
|
12
|
+
|
3
13
|
### 1.6.1
|
4
14
|
2012-03-07
|
5
15
|
|
data/docs/RELEASES.md
CHANGED
@@ -45,3 +45,10 @@ Before each relese to Rubygems.org, the following steps will be taken:
|
|
45
45
|
11. Close out release in JIRA.
|
46
46
|
|
47
47
|
12. Annouce release on mongodb-user and mongodb-dev.
|
48
|
+
|
49
|
+
## Rake Deploy Tasks
|
50
|
+
1. rake deploy:change_version[1.6.1]
|
51
|
+
2. rake deploy:git_prepare
|
52
|
+
3. rake deploy:git_push
|
53
|
+
4. rake deploy:gem_build
|
54
|
+
5. rake deploy:gem_push
|
data/docs/REPLICA_SETS.md
CHANGED
@@ -41,8 +41,8 @@ the state of any secondary node, the automated refresh will ensure that this sta
|
|
41
41
|
|
42
42
|
There are two secenarios in which refresh is helpful and does not raise exceptions:
|
43
43
|
|
44
|
-
|
45
|
-
|
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
46
|
|
47
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
48
|
|
data/docs/TUTORIAL.md
CHANGED
@@ -9,8 +9,11 @@ As always, the [latest source for the Ruby driver](http://github.com/mongodb/mon
|
|
9
9
|
## Installation
|
10
10
|
|
11
11
|
The mongo-ruby-driver gem is served through Rubygems.org. To install, make sure you have the latest version of rubygems.
|
12
|
+
|
12
13
|
gem update --system
|
14
|
+
|
13
15
|
Next, install the mongo rubygem:
|
16
|
+
|
14
17
|
gem install mongo
|
15
18
|
|
16
19
|
The required `bson` gem will be installed automatically.
|
@@ -23,67 +26,68 @@ After installing, you may want to look at the [examples](http://github.com/mongo
|
|
23
26
|
|
24
27
|
## Getting started
|
25
28
|
|
26
|
-
|
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.
|
27
30
|
|
28
|
-
|
31
|
+
irb
|
29
32
|
|
30
|
-
|
31
|
-
require 'mongo'
|
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.
|
32
34
|
|
33
|
-
|
35
|
+
### Using the gem
|
34
36
|
|
35
|
-
|
37
|
+
Use the `mongo` gem via the `require` kernel method.
|
36
38
|
|
37
|
-
|
39
|
+
require 'rubygems' # not necessary for Ruby 1.9
|
40
|
+
require 'mongo'
|
38
41
|
|
39
|
-
|
40
|
-
db = Mongo::Connection.new("localhost").db("mydb")
|
41
|
-
db = Mongo::Connection.new("localhost", 27017).db("mydb")
|
42
|
+
### Making a Connection
|
42
43
|
|
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:
|
44
45
|
|
45
|
-
|
46
|
+
connection = Mongo::Connection.new # (optional host/port args)
|
47
|
+
connection = Mongo::Connection.new("localhost")
|
48
|
+
connection = Mongo::Connection.new("localhost", 27017)
|
46
49
|
|
47
|
-
|
50
|
+
### Listing All Databases
|
48
51
|
|
49
|
-
connection
|
50
|
-
connection.
|
51
|
-
connection.database_info.each { |info| puts info.inspect}
|
52
|
+
connection.database_names
|
53
|
+
connection.database_info.each { |info| puts info.inspect }
|
52
54
|
|
53
|
-
|
54
|
-
connection.drop_database('database_name')
|
55
|
+
The `database_info` method returns a hash mapping database names to the size of the database in bytes.
|
55
56
|
|
56
|
-
|
57
|
+
## Using a Database
|
57
58
|
|
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":
|
59
60
|
|
60
|
-
|
61
|
+
db = connection.db("mydb")
|
62
|
+
db = Mongo::Connection.new.db("mydb")
|
61
63
|
|
62
|
-
|
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.
|
63
65
|
|
64
|
-
|
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).
|
65
67
|
|
66
|
-
|
68
|
+
### Authentication
|
67
69
|
|
68
|
-
and
|
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:
|
69
71
|
|
70
|
-
|
71
|
-
address
|
72
|
+
auth = db.authenticate(my_user_name, my_password)
|
72
73
|
|
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.
|
74
75
|
|
75
|
-
|
76
|
+
## Using a Collection
|
76
77
|
|
77
78
|
You can get a collection to use using the `collection` method:
|
79
|
+
|
78
80
|
coll = db.collection("testCollection")
|
81
|
+
|
79
82
|
This is aliased to the \[\] method:
|
83
|
+
|
80
84
|
coll = db["testCollection"]
|
81
85
|
|
82
|
-
Once you have this collection object, you can now do
|
86
|
+
Once you have this collection object, you can now do create, read, update, and delete (CRUD) functions on persistent storage.
|
83
87
|
|
84
|
-
|
88
|
+
### Creating Documents with `insert`
|
85
89
|
|
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
|
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
|
87
91
|
|
88
92
|
{
|
89
93
|
"name" : "MongoDB",
|
@@ -95,115 +99,158 @@ Once you have the collection object, you can insert documents into the collectio
|
|
95
99
|
}
|
96
100
|
}
|
97
101
|
|
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
|
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.
|
99
103
|
|
100
|
-
doc = {"name" => "MongoDB", "type" => "database", "count" => 1,
|
101
|
-
|
102
|
-
coll.insert(doc)
|
104
|
+
doc = {"name" => "MongoDB", "type" => "database", "count" => 1, "info" => {"x" => 203, "y" => '102'}}
|
105
|
+
id = coll.insert(doc)
|
103
106
|
|
104
|
-
|
107
|
+
We have saved the `id` for future use below. Now the collection has been created and you can list it.
|
105
108
|
|
106
|
-
|
109
|
+
#### Getting a List Of Collections
|
107
110
|
|
108
|
-
|
109
|
-
coll.update({"_id" => doc["_id"]}, doc)
|
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):
|
110
112
|
|
111
|
-
|
113
|
+
db.collection_names
|
112
114
|
|
113
|
-
|
115
|
+
You should see
|
114
116
|
|
115
|
-
|
117
|
+
\["testCollection", "system.indexes"\]
|
116
118
|
|
117
|
-
####
|
119
|
+
#### Adding Multiple Documents
|
118
120
|
|
119
|
-
To
|
121
|
+
To demonstrate some more interesting queries, let's add multiple simple documents to the collection. These documents will have the following form:
|
120
122
|
|
121
|
-
|
122
|
-
|
123
|
+
{
|
124
|
+
"i" : value
|
125
|
+
}
|
123
126
|
|
124
|
-
|
127
|
+
Here's how to insert them:
|
125
128
|
|
126
|
-
|
127
|
-
"info"=>{"x"=>203, "y"=>102}, "type"=>"database", "count"=>1}
|
129
|
+
100.times { |i| coll.insert("i" => i) }
|
128
130
|
|
129
|
-
|
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".
|
130
132
|
|
131
|
-
|
133
|
+
### Reading Documents with `find_one` and `find`
|
132
134
|
|
133
|
-
|
134
|
-
{
|
135
|
-
"i" : value
|
136
|
-
}
|
135
|
+
#### Reading the First Document in a Collection using `find_one`
|
137
136
|
|
138
|
-
|
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.
|
139
138
|
|
140
|
-
|
139
|
+
coll.find_one
|
141
140
|
|
142
|
-
|
141
|
+
and you should something like:
|
143
142
|
|
144
|
-
|
143
|
+
{"_id"=>BSON::ObjectId('4f7b1ea6e4d30b35c9000001'), "name"=>"MongoDB", "type"=>"database", "count"=>1, "info"=>{"x"=>203, "y"=>"102"}}
|
145
144
|
|
146
|
-
|
145
|
+
Note the `_id` element has been added automatically by MongoDB to your document.
|
147
146
|
|
148
|
-
|
147
|
+
#### Reading All of the Documents with a Cursor using `find`
|
149
148
|
|
150
|
-
|
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 }
|
151
152
|
|
152
|
-
|
153
|
+
and that should print all 101 documents in the collection. You can take advantage of `Enumerable#to_a`.
|
153
154
|
|
154
|
-
|
155
|
+
puts coll.find.to_a
|
155
156
|
|
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.
|
157
158
|
|
158
|
-
|
159
|
+
#### Specific Queries
|
159
160
|
|
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:
|
161
162
|
|
162
|
-
|
163
|
+
coll.find("_id" => id).to_a
|
163
164
|
|
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
|
165
168
|
|
166
169
|
and it should just print just one document:
|
167
170
|
|
168
|
-
{"_id"
|
171
|
+
{"_id"=>BSON::ObjectId('4f7b20b4e4d30b35c9000049'), "i"=>71}
|
172
|
+
|
173
|
+
#### Counting Documents in a Collection
|
174
|
+
|
175
|
+
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.
|
176
|
+
|
177
|
+
coll.count
|
178
|
+
|
179
|
+
and it should print `101`.
|
169
180
|
|
170
181
|
#### Getting a Set of Documents With a Query
|
171
182
|
|
172
183
|
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
184
|
|
174
|
-
coll.find("i" => {"$gt" => 50}).
|
185
|
+
puts coll.find("i" => {"$gt" => 50}).to_a
|
175
186
|
|
176
187
|
which should print the documents where i > 50. We could also get a range, say 20 < i <= 30:
|
177
188
|
|
178
|
-
coll.find("i" => {"$gt" => 20, "$lte" => 30}).
|
189
|
+
puts coll.find("i" => {"$gt" => 20, "$lte" => 30}).to_a
|
179
190
|
|
180
|
-
#### Selecting a
|
191
|
+
#### Selecting a Subset of Fields for a Query
|
181
192
|
|
182
|
-
Use the `:fields` option
|
193
|
+
Use the `:fields` option to specify fields to return.
|
183
194
|
|
184
|
-
coll.find("
|
195
|
+
puts coll.find("_id" => id, :fields => ["name", "type"]).to_a
|
185
196
|
|
186
197
|
#### Querying with Regular Expressions
|
187
198
|
|
188
199
|
Regular expressions can be used to query MongoDB. To find all names that begin with 'a':
|
189
200
|
|
190
|
-
coll.find({"name" => /^
|
201
|
+
puts coll.find({"name" => /^M/}).to_a
|
191
202
|
|
192
203
|
You can also construct a regular expression dynamically. To match a given search string:
|
193
204
|
|
205
|
+
params = {'search' => 'DB'}
|
194
206
|
search_string = params['search']
|
195
207
|
|
196
208
|
# Constructor syntax
|
197
|
-
coll.find({"name" => Regexp.new(search_string)})
|
209
|
+
puts coll.find({"name" => Regexp.new(search_string)}).to_a
|
198
210
|
|
199
211
|
# Literal syntax
|
200
|
-
coll.find({"name" => /#{search_string}/})
|
212
|
+
puts coll.find({"name" => /#{search_string}/}).to_a
|
201
213
|
|
202
214
|
Although MongoDB isn't vulnerable to anything like SQL-injection, it may be worth checking the search string for anything malicious.
|
203
215
|
|
216
|
+
### Updating Documents with `update`
|
217
|
+
|
218
|
+
We can update the previous document using the `update` method. There are a couple ways to update a document. We can rewrite it:
|
219
|
+
|
220
|
+
doc["name"] = "MongoDB Ruby"
|
221
|
+
coll.update({"_id" => id}, doc)
|
222
|
+
|
223
|
+
Or we can use an atomic operator to change a single value:
|
224
|
+
|
225
|
+
coll.update({"_id" => id}, {"$set" => {"name" => "MongoDB Ruby"}})
|
226
|
+
|
227
|
+
Verify the update.
|
228
|
+
|
229
|
+
puts coll.find("_id" => id).to_a
|
230
|
+
|
231
|
+
Read [more about updating documents|Updating].
|
232
|
+
|
233
|
+
### Deleting Documents with `remove`
|
234
|
+
|
235
|
+
Use the `remove` method to delete documents.
|
236
|
+
|
237
|
+
coll.count
|
238
|
+
coll.remove("i" => 71)
|
239
|
+
coll.count
|
240
|
+
puts coll.find("i" => 71).to_a
|
241
|
+
|
242
|
+
The above shows that the count has been reduced and that the document can no longer be found.
|
243
|
+
|
244
|
+
Without arguments, the `remove` method deletes all documents.
|
245
|
+
|
246
|
+
coll.remove
|
247
|
+
coll.count
|
248
|
+
|
249
|
+
Please program carefully.
|
250
|
+
|
204
251
|
## Indexing
|
205
252
|
|
206
|
-
|
253
|
+
### Creating An Index
|
207
254
|
|
208
255
|
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
256
|
|
@@ -215,7 +262,21 @@ To specify complex indexes or a descending index you need to use a slightly more
|
|
215
262
|
# Explicit "ascending"
|
216
263
|
coll.create_index([["i", Mongo::ASCENDING]])
|
217
264
|
|
218
|
-
|
265
|
+
Use the `explain` method on the cursor to show how MongoDB will run the query.
|
266
|
+
|
267
|
+
coll.find("_id" => id).explain
|
268
|
+
coll.find("i" => 71).explain
|
269
|
+
coll.find("type" => "database").explain
|
270
|
+
|
271
|
+
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.
|
272
|
+
|
273
|
+
### Getting a List of Indexes on a Collection
|
274
|
+
|
275
|
+
You can get a list of the indexes on a collection.
|
276
|
+
|
277
|
+
coll.index_information
|
278
|
+
|
279
|
+
### Creating and Querying on a Geospatial Index
|
219
280
|
|
220
281
|
First, create the index on a field containing long-lat values:
|
221
282
|
|
@@ -224,12 +285,48 @@ First, create the index on a field containing long-lat values:
|
|
224
285
|
Then get a list of the twenty locations nearest to the point 50, 50:
|
225
286
|
|
226
287
|
people.find({"loc" => {"$near" => [50, 50]}}, {:limit => 20}).each do |p|
|
227
|
-
puts p.inspect
|
288
|
+
puts p.inspect
|
228
289
|
end
|
229
290
|
|
230
|
-
|
291
|
+
## Dropping
|
292
|
+
|
293
|
+
### Drop an Index
|
294
|
+
|
295
|
+
To drop a secondary index, use the `drop_index` method on the collection.
|
296
|
+
|
297
|
+
coll.drop_index("i_1")
|
298
|
+
coll.index_information
|
299
|
+
|
300
|
+
The dropped index is no longer listed.
|
301
|
+
|
302
|
+
### Drop All Indexes
|
303
|
+
|
304
|
+
To drop all secondary indexes, use the `drop_indexes` method on the collection.
|
305
|
+
|
306
|
+
coll.drop_indexes
|
307
|
+
coll.index_information
|
308
|
+
|
309
|
+
Only the primary index "_id_" is listed.
|
310
|
+
|
311
|
+
### Drop a Collection
|
312
|
+
|
313
|
+
To drop a collection, use the `drop` method on the collection.
|
314
|
+
|
315
|
+
coll.drop
|
316
|
+
db.collection_names
|
317
|
+
|
318
|
+
The dropped collection is no longer listed. The `drop_collection` method can be used on the database as an alternative.
|
319
|
+
|
320
|
+
db.drop_collection("testCollection")
|
321
|
+
|
322
|
+
### Drop a Database
|
323
|
+
|
324
|
+
To drop a database, use the `drop_database` method on the connection.
|
325
|
+
|
326
|
+
connection.drop_database("mydb")
|
327
|
+
connection.database_names
|
231
328
|
|
232
|
-
|
329
|
+
The dropped database is no longer listed.
|
233
330
|
|
234
331
|
## Database Administration
|
235
332
|
|