The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".
The following errata were submitted by our customers and approved as valid errors by the author or editor.
Version |
Location |
Description |
Submitted By |
Date submitted |
Date corrected |
Mobi |
Page Location 563
Location 563 |
Or if you?re on Windows, run this: $ mongod.exe
Obviously the $ is UNIX not windows
Note from the Author or Editor: Good point, it should be:
> mongod.exe
|
Ninja Assassin |
Jun 03, 2013 |
Jun 06, 2014 |
PDF |
Page Page 63
2nd paragraph |
"the document is returned because 25 matches the first clause (it is greater than 25)"
should be changed to
"the document is returned because 25 matches the first clause (it is greater than 10)"
|
Johan Roch |
Dec 08, 2013 |
Jun 06, 2014 |
PDF |
Page 29,30
3rd paragraph |
On Chapter 3
"Batch Insert"
I think it should be "Bulk Insert"
and Code:
> db.foo.batchInsert([{"_id" : 0}, {"_id" : 1}, {"_id" : 2}])
Wed May 22 12:20:40.234 JavaScript execution failed: TypeError: Property 'batchInsert' of object test.foo is not a function
> db.foo.batchinsert([{"_id" : 0}, {"_id" : 1}, {"_id" : 2}])
Wed May 22 12:21:08.443 JavaScript execution failed: TypeError: Property 'batchinsert' of object test.foo is not a function
I think It should be! "db.foo.insert"
> db.foo.insert([{"_id" : 0}, {"_id" : 1}, {"_id" : 2}])
>
Note from the Author or Editor: It is called "batch insert," however you are correct about the function name. It should be:
> db.foo.insert([{"_id" : 0}, {"_id" : 1}, {"_id" : 2}])
|
Surachart Opun |
May 21, 2013 |
Jun 06, 2014 |
Printed |
Page 29
Batch Insert |
According to http://docs.mongodb.org/manual/core/write-operations/ "batch insert" is now known as "bulk insert".
The final paragraph on page 29 should read something like: "You can try this out using the insert function, which since release 2.2 has optionally taken an array of documents to bulk insert."
Note from the Author or Editor: Hmm, the drivers still use batch insert so it's probably still worth a mention, but this should probably be retitled Bulk Insert.
|
Simon Dismore |
Jun 09, 2013 |
Jun 06, 2014 |
PDF |
Page 30
2nd--to-last paragraph |
"it check's the" → "it checks the"
|
Karl Broman |
Jun 20, 2015 |
|
PDF |
Page 31
last paragraph |
Code : > var timeRemoves = function() {
Please help check.
It should be
> db.tester.findOne();
Tested:
> db.findOne();
Wed May 22 12:44:59.420 JavaScript execution failed: TypeError: Property 'findOne' of object test is not a function
> db.tester.findOne();
{
"_id" : ObjectId("519c5a2b96aa44edfb12e196"),
"foo" : "bar",
"baz" : 456255,
"z" : -456245
}
>
Note from the Author or Editor: ... db.findOne(); // makes sure the remove finishes before continuing
should be:
... db.tester.findOne(); // makes sure the remove finishes before continuing
|
Surachart Opun |
May 21, 2013 |
Jun 06, 2014 |
PDF |
Page 39
2rd paragraph |
The follow code isn't correct
db.movies.find({"genre" : "horror"},
... {"$push" : {"top10" : {
... "$each" : [{"name" : "Nightmare on Elm Street", "rating" : 6.6},
... {"name" : "Saw", "rating" : 4.3}],
... "$slice" : -10,
... "$sort" : {"rating" : -1}}}})
The correct code is
db.movies.update({"genre" : "horror"},
{"$push" : {"top10" : {
"$each" : [{"name" : "Nightmare on Elm Street", "rating" : 6.6},
{"name" : "Saw", "rating" : 4.3}],
"$slice" : -10,
"$sort" : {"rating" : -1}}}})
With "update" instead "find"
|
Barno |
Aug 26, 2014 |
|
Printed, PDF, ePub, Mobi, , Other Digital Version |
Page 42
Code samples |
db.blog.update should be db.blog.posts.update in both examples.
|
![Kristina Chodorow](http://cdn.oreillystatic.com/images/people/weblogs/kristina_chodorow.jpg) Kristina Chodorow |
Aug 29, 2014 |
|
PDF |
Page 44
3rd paragraph |
You suggest replacing the "$inc" function with a "$push" in an update.
However when I use the "$push" I get the following:
> var timeInc = function() {
... var start = (new Date()).getTime();
...
... for (var i=0; i<100000; i++) {
... db.tester.update({}, {"$push" : {"x" : 1}});
... db.getLastError();
... }
...
... var timeDiff = (new Date()).getTime() - start;
... print("Updates took: " + timeDiff + "ms");
... }
> timeInc()
Updates took: 147255ms
Cannot apply $push/$pushAll modifier to non-array
> db.tester.find()
{ "_id" : ObjectId("52aaa4daaf47dcd9bc8e573f"), "x" : 1 }
Can you please explain why I did not get the same results as when using the "$inc"?
Also, what is meant by " Cannot apply $push/$pushAll modifier to non-array"?
Note from the Author or Editor: You must remove the document from the "tester" collection before running the $push example. Otherwise, you're trying to $push a value onto an integer and $pushing only works with arrays.
The text should mention that the collection should be dropped between the two runs (and should specify that it's an upsert, not an update).
Change the update call to this:
should be:
Remove the document and change the update call to this:
|
Anonymous |
Dec 13, 2013 |
Jun 06, 2014 |
PDF |
Page 44
3rd paragraph |
How can the $push command be used to increment an integer number like the $inc?
> db.tester.remove()
> db.tester.update({}, {"$push" : {x : 1}})
> db.tester.find()
> db.tester.insert({x : [1]});
> db.tester.find()
{ "_id" : ObjectId("52b02cded47ab1c03e25b3e6"), "x" : [ 1 ] }
> db.tester.update({}, {"$push" : {x : 1}})
> db.tester.find()
{ "_id" : ObjectId("52b02cded47ab1c03e25b3e6"), "x" : [ 1, 1 ] }
The upsert will not work, the tester collection must already exist with an array of integer. Then using the $push command as you suggest would create an array of "1's" of size 100001, not an array of size "1" with a value of 100001. Would that not be correct? If I am in error would greatly appreciate you pointing out where I have gone wrong.
Could you please publish the code you used on your MacBook Air.
Note from the Author or Editor: You cannot use $push to increment. The end result of 10000 $pushes should be an array with 100001 1s in it.
The first update should be an upsert.
db.tester.update({}, {"$inc" : {"x" : 1}});
should be:
db.tester.update({}, {"$inc" : {"x" : 1}}, {upsert : true});
|
Anonymous |
Dec 17, 2013 |
Jun 06, 2014 |
PDF |
Page 49
2nd paragraph |
There's a missing closing bracket in the findAndModify example:
"update" : {"$set" : {"status" : "RUNNING"}})
should be
"update" : {"$set" : {"status" : "RUNNING"}}})
Note from the Author or Editor: You are correct, thanks for catching that!
|
Giorgio Donnini |
Jun 03, 2013 |
Jun 06, 2014 |
Printed |
Page 70
Paginating results without skip |
In this paragraph a workaround is presented how to
avoid using large skips as they are usually slow. But I think
this workaround only works if the values of "date" are unique
in the collection. Suppose the collection is sorted by date descending.
Suppose that in this sorted collection, the documents between
No 95 and No 105 have the same values for date. Then this
workaround will not work. The 2nd page will actually return the
documents from No 106 on which is not the desired behavior.
Note from the Author or Editor: If the field is not unique, the client could be modified to track of the _id of the last date on the previous page.
|
Peter Petrov |
Feb 15, 2014 |
Jun 06, 2014 |
Printed |
Page 70
Paginating results without skip |
In this example there, actually this part:
var page2 = db.foo.find({"date" : {"$gt" : latest.date}});
should be:
var page2 = db.foo.find({"date" : {"$lt" : latest.date}});
because the whole example is talking about retrieving and
displaying documents in descending order based on "date".
So for the second page, we should use "$lt", and not "$gt".
|
Peter Petrov |
Feb 19, 2014 |
Jun 06, 2014 |
PDF |
Page 71
3rd code example |
Regarding finding a random document in a collection, this line is incorrect:
result = db.foo.findOne({"random" : {"$lt" : random}})
The author is using it guard against the case where the random number is bigger than the largest random key of documents in the collection. However, it will also fail to match (return null) if the only documents in the collection have random key values equal to the random number in the search criteria.
The solution is the use "$lte" instead of "$lt".
|
JeremyBower |
May 10, 2013 |
Jun 06, 2014 |
Printed |
Page 72
$maxscan paragraph |
"This can be useful if you want a query to not to take too long..."
The "to not to take too long" part sounds like a typo.
I guess it should be "to not take too long" or "not to take too long".
Note from the Author or Editor: Change "to not to take too long" to "to not take too long".
|
Peter Petrov |
Feb 17, 2014 |
Jun 06, 2014 |
Printed |
Page 72
$maxscan code example |
This code fragment
db.foo.find(criteria)._addSpecial("$maxscan", 20)
should actually read
db.foo.find(criteria)._addSpecial("$maxScan", 20)
because $maxscan does not seem to work i.e.
it does not limit anything. $maxScan does.
It is case-sensitive.
Note from the Author or Editor: Change both instances of $maxscan to $maxScan.
|
Peter Petrov |
Feb 26, 2014 |
Jun 06, 2014 |
Printed |
Page 75
runCommand example |
There's this text on page 76:
"A database command always returns a document containing the key "ok". If "ok"is 1, the command was successful; and if it is 0, the command failed for some reason."
But the code examples on pages 75-77 are not consistent with respect to the ok values. Some show true/false, some show 1/0.
Note from the Author or Editor: This should be changed to say that ok always indicates success or failure, either with true/false or 1/0.
change "If "ok" is 1, the command was successful; and if it is 0, the command failed for some reason." to "If "ok" is a true value (1, 1.0, or true)
then the command was successful. If it is false then the command failed for some reason."
|
Peter Petrov |
Feb 26, 2014 |
Jun 06, 2014 |
Printed |
Page 83
last paragraph |
"However, indexes have their price: every write (insert, update, or delete) will take longer for every index you add."
Actually for updates isn't it true that it has an additional price only if the update updates a field which is part of the keys of some index? I think it is so but I am not 100% sure. I don't see why updating a field which is part of none of the indexes will have an additional price (price for reorganizing some of the indexes).
Note from the Author or Editor: It depends. If the update makes the document bigger and it has to be moved, then all of the indexes must be updated. But in other cases you are correct. This should be clarified.
However, indexes have their price: every write (insert, update, or delete) will take longer for every Introduction to index you add"
should be:
"However, indexes have their price: every write that touches an indexed field (insert, update, or delete) will take longer for every index you add"
|
Peter Petrov |
Mar 10, 2014 |
Jun 06, 2014 |
PDF |
Page 94
First paragraph below "OR queries" heading |
Typo:
This only exception to this rule is "$or".
Should be
The only exception to this rule is "$or".
|
JeremyBower |
May 10, 2013 |
Jun 06, 2014 |
Printed |
Page 94
last textual (non-code) paragraph |
"This only exception to this rule is"
I think this should read:
"The only exception to this rule is"
This is just a very minor thing though.
|
Peter Petrov |
Mar 10, 2014 |
Jun 06, 2014 |
PDF |
Page 95
3rd paragraph |
This paragraph has incorrect find statements:
When running "$in" queries there is no way, other than sorting, to control the order of documents returned. For example, {"x" : [1, 2, 3]} will return documents in the same order as {"x" : [3, 2, 1]}.
It's missing the $in operator. It should be:
When running "$in" queries there is no way, other than sorting, to control the order of documents returned. For example, {"x" : {$in, [1, 2, 3]}} will return documents in the same order as {"x" : {$in, [3, 2, 1]}}.
Note from the Author or Editor: Almost, it should be:
For example, {"x" : {"$in" : [1, 2, 3]}} will return documents in the same order as {"x" : {"$in" : [3, 2, 1]}}.
|
JeremyBower |
May 10, 2013 |
Jun 06, 2014 |
Printed |
Page 98
the paragraph before the last one |
The most basic type of explain() is on a query that doesn?t use an index. You can tell
that a query doesn?t use an index because it uses a "BasicCursor". Conversely, most queries that use an index use a BtreeCursor (some special types of indexes, such as geospatial indexes, use their own type of cursor).
I wonder why "BasicCursor" is in parentheses and BtreeCursor is not. I think either both should be with or without parentheses. I realize this is very minor though.
Note from the Author or Editor: Put quotes around BtreeCursor.
|
Peter Petrov |
Mar 25, 2014 |
Jun 06, 2014 |
Printed |
Page 100
nscannedObjects paragraph |
"This is a count of the number of times MongoDB had to follow an index pointer to the actual document on disk"
Not fully sure but ... "a count of the number of times" sounds like a tautology to me.
Note from the Author or Editor: change to "This is the number of times MongoDB had to"
|
Peter Petrov |
Mar 25, 2014 |
Jun 06, 2014 |
Printed |
Page 106
code below 3rd paragraph |
Collection name is missing in the code:
> db.ensureIndex( ...
should be, for example:
> db.users.ensureIndex( ...
Note from the Author or Editor: Whoops.
|
Simon Dismore |
Jun 09, 2013 |
Jun 06, 2014 |
Printed |
Page 110
Figure 6-2 |
Figure 6-2 is inconsistent with Figure 6-1. In 6-1 the left-hand snowflake is older than the right-hand-snowflake, so in 6-2 the left-hand snowflake should be replaced by the new document.
Note from the Author or Editor: I think the illustrators must have translated it incorrectly from the original. You're actually the first one to notice in two editions!
|
Simon Dismore |
Jun 09, 2013 |
Jun 06, 2014 |
Printed, PDF |
Page 114
last line on page, code |
db.foo.ensureIndex({"lastUpdated" : 1}, {"expireAfterSecs" : 60*60*24})
should be...
db.foo.ensureIndex({"lastUpdated" : 1}, {"expireAfterSeconds" : 60*60*24})
The error occurs in the code on page 115 also.
|
David Alexis |
Feb 17, 2014 |
Jun 06, 2014 |
Printed |
Page 114
No-_id collections |
"However, you can create collections with "_id" indexes by setting the autoIndexId option to false when calling createCollection."
I think it should read:
"However, you can create collections without "_id" indexes by setting the autoIndexId option to false when calling createCollection."
|
Peter Petrov |
Mar 25, 2014 |
Jun 06, 2014 |
Printed |
Page 114
TTL Indexes |
"If you need a more flexible age-out system, time-to-live (TTL) indexes allow you to set a timeout for each document."
I think this ("for each document") somehow implies that the timeout value is per document while actually it seems to be per index, the expireAfterSecs value is one per index, not one per document. I mean, we cannot set different expireAfterSecs on each document.
Note from the Author or Editor: What I was trying to say was that documents do not have an implicit timestamp. You create a TTL index on a field, but you can give the documents any value you want for that field (or none at all) so every document can live for a different length of time.
Perhaps this could be phrased better.
|
Peter Petrov |
Mar 26, 2014 |
Jun 06, 2014 |
Printed |
Page 115
example after 3rd paragraph |
db.runCommand({"collMod" : "someapp.cache", "expireAfterSecs" : 3600})
I think this is an incorrect syntax. The correct one seems to be:
db.runCommand( {"collMod" : "someapp.cache" , "index" : { "keyPattern" : {"lastUpdated" : 1} , "expireAfterSeconds" : 3600 } } );
Pages 114 and 115 talk about TTL indexes, not about TTL collections. I am not sure actually if there're TTL collections or not. But the command in the book apparently doesn't modify an index, it modifies a collection (if its syntax is allowed at all).
This is very confusing.
If I run the original command, I get these errors.
> db.runCommand({"collMod" : "test_ttl", "expireAfterSeconds" : 3600})
{ "ok" : 0, "errmsg" : "unknown option to collMod: expireAfterSeconds" }
> db.runCommand({"collMod" : "test_ttl", "expireAfterSecs" : 3600})
{ "ok" : 0, "errmsg" : "unknown option to collMod: expireAfterSecs" }
Note from the Author or Editor: I think that this changed since the book was written. See http://docs.mongodb.org/manual/reference/command/collMod/#index for the correct format.
Change db.runCommand({"collMod" : "someapp.cache", "expireAfterSecs" : 3600}) to their suggestion:
db.runCommand( {"collMod" : "someapp.cache" , "index" : { "keyPattern" : {"lastUpdated" : 1} , "expireAfterSeconds" : 3600 } } );
|
Peter Petrov |
Mar 26, 2014 |
Jun 06, 2014 |
Printed |
Page 119
paragraph 6 |
"You cannot use a multikey field for any of the prefix or postfix index fields."
I tested this by creating a collection which has these fields:
"dt" : some integers here in the different docs (one integer per doc)
"txt" : some texts here (one text/string per doc)
"author" : some texts/strings, one per doc (but also an array of integers in just one of the documents)
Then I am able to do
db.blog.ensureIndex({"dt" : 1, "txt" : "text", "author" : 1});
contrary to what the book says. I mean, "author" is a postfix field here,
it is multikey (as it contains an array), but I can still create this index.
Seems either I am missing something, or maybe something has
changed since the book was written. I am testing this on version 2.4.8.
Note from the Author or Editor: Remove the sentence "You cannot use a multikey field for any of the prefix or postfix index fields."
|
Peter Petrov |
Apr 01, 2014 |
Jun 06, 2014 |
Printed |
Page 125
"files_id" description |
"The "_id" of the file document that contains the metadata for this chunk."
Not fully sure as it's just a language remark... but this sounds like "the chunk's metadata", and not like "that's the metadata of the whole file" (while actually the latter is true, I think; this becomes clear from the next page).
Note from the Author or Editor: "The "_id" of the file document that contains the metadata for this chunk" should be changed to "The "_id" of the file document that contains the metadata for the file this chunk is from."
|
Peter Petrov |
Apr 01, 2014 |
Jun 06, 2014 |
Printed |
Page 126
3rd paragraph from the bottom up |
"You might want to keep information such as download count, mimetype, or user rating with a file's metadata."
"mimetype" - I think it should be spelled as "mime type" or even better as "MIME type".
|
Peter Petrov |
Apr 01, 2014 |
Jun 06, 2014 |
Printed |
Page 127
last paragraph |
I think this:
"maps to a aggregation framework operator"
should read:
"maps to an aggregation framework operator"
|
Peter Petrov |
May 04, 2014 |
Jun 06, 2014 |
Printed |
Page 132
Date expressions paragraph |
"This would calculate many years"
I think this should read
"This would calculate how many years"
|
Peter Petrov |
Apr 29, 2014 |
Jun 06, 2014 |
Printed |
Page 132
Date expressions paragraph |
"Each of these date types is basically the same"
I don't think these are date types, I think they are "date operations"
or "date operators" but date types definitely sounds incorrect to me.
Note from the Author or Editor: Change to "date operators"
|
Peter Petrov |
May 04, 2014 |
Jun 06, 2014 |
Printed |
Page 134
Right before "A projection example" |
"you can use this conditionals to detect missing values and pop‐
ulate them"
I think this should read:
"you can use these conditionals to detect missing values and pop‐
ulate them"
|
Peter Petrov |
Apr 29, 2014 |
Jun 06, 2014 |
Printed |
Page 135
first paragraph, second bullet |
"and we wanted to organize student into groups"
I think it should read
"and we wanted to organize the students into groups"
|
Peter Petrov |
May 04, 2014 |
Jun 06, 2014 |
Printed |
Page 135
Arithmetic operators paragraph |
There are two operators that can be used to compute numeric val‐
ues from fields: "$sum"and "$average".
Here this "$average" should read "$avg".
On the next page 136, it is correctly written as "$avg".
|
Peter Petrov |
May 04, 2014 |
Jun 06, 2014 |
PDF |
Page 136
$avg example |
|
![Kristina Chodorow](http://cdn.oreillystatic.com/images/people/weblogs/kristina_chodorow.jpg) Kristina Chodorow |
Sep 27, 2013 |
Jun 06, 2014 |
Printed |
Page 136
$avg example |
> db.sales.aggregate(
... {
... "$group" : {
... "_id" : "$country",
... "totalRevenue" : {"$average" : "$revenue"},
... "numSales" : {"$sum" : 1}
... }
... })
I think "totalRevenue" should read "averageRevenue".
That makes more sense.
|
Peter Petrov |
Apr 09, 2014 |
Jun 06, 2014 |
Printed |
Page 138
$unwind example |
In the output from $unwind,
I think that "results" should read "result"
(unless it was otherwise in previous versions of
MongoDB; I tested it in version 2.4.8).
|
Peter Petrov |
May 06, 2014 |
Jun 06, 2014 |
PDF |
Page 161
Last paragraph, first sentence |
This sentence has a typo:
"If your document has one field that grows, try to keep is as the last field in the document (but before "garbage")."
"try to keep is" -> "try to keep it"
|
JeremyBower |
May 10, 2013 |
Jun 06, 2014 |
Printed, PDF, ePub, Mobi, |
Page 379
2nd paragraph |
The closing paren is 4 words late.
|
![Kristina Chodorow](http://cdn.oreillystatic.com/images/people/weblogs/kristina_chodorow.jpg) Kristina Chodorow |
Jul 08, 2013 |
Jun 06, 2014 |