By Developers, For Developers

Historical errata for Seven Databases in Seven Weeks

PDF PgPaper PgTypeDescriptionFixed onComments
16TYPO

…but it’s roots…

should be

…but its roots…

2011-12-16
16TYPO

1970’s and 1980’s should be 1970s and 1980s (no apostrophes)

2011-12-16
17TYPO

“Before we too deeply” => “Before we dive? go? too deeply”

2011-12-16
57TYPO

“all node’s are equal” -> all nodes are equal

2011-12-16
59ERROR

in HTML body should be

2011-12-16
63TYPO

“Tn other words” -> In other words

2011-12-16
151TYPO

“Caveat emptor”, not “Cavet emptor”
This message was brought to you by the Latin Spelling Police :)

2011-12-16
23TYPO

RDBMS’s => RDBMSs (RDBMSes ?)

plurals never take an apostrophe =)

2011-12-16
65ERROR

hotel.rb uses the incorrect range specifier, making 101 floors of 101 rooms each. (It also means that “room” 200 is on the first floor.)

The author probably meant 1…100 for both sequences.

2011-12-16
66ERROR

total_count = rooms_by_style[room.style]
should read:
total_count = capacity_by_style[room.style]

2011-12-16
74TYPO

theorm -> theorem

2011-12-16
30SUGGEST

I’m not sure what you mean exactly in the box titled ‘GROUP BY in MySQL’, but window functions are not limited to partitions over columns: they can also apply to ranges of rows around the current one and can be used to compute running averages or running totals.

This cannot be mimicked simply by ‘GROUP BY’, but requires possibly complex subqueries.

2011-12-31
18ERROR

The code to demonstrate duplicate keys on insert would not generate a duplicate key. Looks like a confusion of UK and GB when inserting the United Kingdom.

2011-12-16it should, because when we created the table we used "country_name text UNIQUE"... Trying to add a second "United Kingdom" will throw the error.
18SUGGEST

Isn’t it generally good practice the name relations in the singular. Eg Country rather the Countries?

2011-12-16This is debatable. I was a "singular" stickler for years, but after several ORB frameworks started pluralizing - it's just a matter of preference anymore.
15TYPO

FAA stands for Federal Aviation Administration (not Authority). Used to work for them for 3 years :)

2011-12-16
41ERROR

The proposed index will not work for the case insensitive queries using ILIKE or the case insensitive regex operator (as can be seen if you use EXPLAIN).

Instead, what can work is:
CREATE INDEX movies_title_pattern ON movies (lower(title) text_pattern_ops);

then the query
SELECT title FROM movies WHERE lower(title) LIKE ‘stardust_%’;
will use the index as intended.

The index cannot be used for negative regex, so the other query will not use it.

2011-12-16
22TYPO

This isn’t exactly an error, but something that isn’t clear to someone who isn’t familiar with postgresql. We’re instructed to create an events table, but the readers haven’t yet seen the integer type that they need to make a foreign key to the venue table. They may mistakenly make it of type ‘SERIAL’, and not know what went wrong.

There is certainly value in having them discover on their own, but if you haven’t touched databases, this could be confusing.

2011-12-16
27ERROR

book=# insert into events values (‘Your Favorite Band’, ‘2012-02-06 21:00’, ‘2012-02-06 23:00’, (select venue_id from venues where name = ‘Crystal Ballroom’) );

yields

ERROR: invalid input syntax for integer: “Your Favorite Band”
LINE 1: insert into events values (‘Your Favorite Band’, ’2012-02-06…

need to include columns, like:

insert into events (title, starts, ends, venue_id) values (‘Your Favorite Band’, ‘2012-02-06 21:00’, ‘2012-02-06 23:00’, (select venue_id from venues where name = ‘Crystal Ballroom’) );

2011-12-31
27TYPO

The query:

select count(title) from events where title like ‘Day’;

should actually return 3 rows if you’ve been following along closely, not 2. You’ll have entered April’s Fools Day and Christmas Day back on day 1. In the text immediately preceding, you added “Valentine’s Day”.

2011-12-16
32ERROR

The stored procedure does not run as written on my machine.

INSERT INTO events VALUES (title, starts, ends, the_venue_id);

Fails to run, returning the error:

book=# SELECT add_event (‘House Party’, ‘2012-05-03 23:00’, ‘2012-05-04 02:00’, ‘Run’‘s House’, ‘97205’, ‘us’);
NOTICE: Venue found 4
ERROR: column “event_id” is of type integer but expression is of type text

In order to make this work, I had to specify column names. This was slightly complicated by the fact that the column names are the same as the variables that are being used to call the function. I had to rename the incoming column names throughout the function. Maybe there is a better way to do this in postgres, though I’m not aware of how to do so.

2011-12-16
211SUGGEST

It’s ironic that Donald Sutherland shows up as extremely connected, since he played in the movie “Six degrees of separation”! (and Kevin Bacon didn’t) :)

2011-12-16
8TYPO

Second bullet: ridged -> rigid

2011-12-16
213TYPO

“trasaction” should be “transaction” (3 instances on this page)

2011-12-16
16TYPO

All in the ‘So What’s With the Name?’ box at the top of the page:

Missing ‘g’ in PostgreSQL: “PostregSQL”

Also you probably mean ‘incarnation’ rather than ‘incantation’ here: “in the current project incantation since 1995”

And “its roots” rather than “it’s roots”. (I.e. no possessive apostrophe.)

Same with “1970’s” and “1980’s” - inappropriate possessive apostrophe. Again in “to denote it’s
rather new SQL support” - should be “its”.

2011-12-16
17TYPO

Before we too deeply into Postgres it would be good to familiarize yourself with this useful tool. It’s worth looking over (or brushing up on) a few common commands, like SELECT or CREATE TABLE.

should be

Before we dig to…

2011-12-16
45ERROR

The book says this:

If you have German installed, we can try this.

SELECT ts_lexize(‘german’, ‘was machst du gerade?’)

to_tsvector
——————-
‘gerad’: 4 ‘mach’: 2

The sql statement there doesn’t match the result. The result is for to_tsvector, not for ts_lexize. Additionally, it seems like you really want to have an example of ts_lexize, maybe something like:

SELECT ts_lexize(‘german_stem’, ‘Wo wohnst du?’);

2011-12-31
59ERROR

Putting a new value returns a 200 code. The v (verbose) attribute in curl out puts this header line:
< HTTP/1.1 200 OK

Actually, unless you add showbody=true, the reply code is 204 No Content
on Riak version 1.0.2.

2011-12-31
61ERROR

What we attempt to associate cage #2 with ace, we use the following:

curl -X PUT htt p://localhost:8091/riak/cages/2 \\
-H “Content-Type: application/json” \\
-H “Link:;riaktag=\\”in\\“, ;riaktag=\\”next_to\\“”\\
-d ‘{“room” : 101}’

If you paste this into your terminal verbatim, it won’t work because on the third line there needs to be a space before the backslash (right after the \\“next_to\\”"

2011-12-16
61SUGGEST

Starting on this page, I noticed that sometimes you’ve started to use localhost and other times you use 127.0.0.1. While they are similar, is there any chance that there is someone out there that might be confused by this?

2011-12-31
67SUGGEST

There’s nothing specifically grammatically or syntactically wrong that I’ve noticed, but the “Mapreduce in Riak” section seems a little bit awkward. I ended up reading it a few times before it sank in. That’s unusual because I’ve used mapreduce on hadoop and understand it pretty well. I think it might have something to do with talking about the specific parts of the request - “inputs” and “query” before we had actually seen an example of how to call them in Riak.

2011-12-31
84ERROR

We update bruiser’s data and we are supposed to get the following response:

$ curl -i http ://localhost:8091/riak/animals/bruiser
X-Riak-Vclock: a85hYGBgzGDKBVIs7NtEXmUwJTLmsTI8FMs5zpcFAA==
{“score” : 3}

With my version of riak, you won’t get the {“score”: 3} part. You have to add “?return_body=true” like this:

$ curl -i http ://localhost:8091/riak/animals/bruiser?return_body=true

Not sure if that might just be related to my version of riak.

2011-12-16
89ERROR

The search feature in standard Riak is enabled in app.config (the same way luwak is), and requires no separate download.

Also, by default the search is case sensitive. The index schema must be updated first to declare the text fields.

2011-12-16
32ERROR

The sql script code/postgres/add_event.sql seems to have an error.

SELECT add_event(‘House Party’, ‘2012-05-03 23:00’, ‘2012-05-04 02:00’, ‘Run’‘s House’, ‘97205’, ‘us’);

The above statement throws the below error.

NOTICE: Venue found 5
ERROR: column “event_id” is of type integer but expression is of type text
LINE 1: INSERT INTO events VALUES (title, starts, ends, the_venue_id…
^
HINT: You will need to rewrite or cast the expression.
QUERY: INSERT INTO events VALUES (title, starts, ends, the_venue_id)
CONTEXT: PL/pgSQL function “add_event” line 23 at SQL statement

2011-12-16
91SUGGEST

In Day 3 homework for Riak, you suggest that we find “Riak function contrib lists”. You may want instead suggest that we should find “Riak function contrib mailing lists”.

I only mention it because I spent a few minutes looking through the repo for a “lists” function before I realized that you meant mailing lists.

2011-12-16
147ERROR

The example for $not in the book does not work with mongoDB 2.0.2. Trying it proceeds the error
error: { “$err” : “invalid use of $not”, “code” : 13034 }

It seems $not has to be directly applied to another $ operator, which is not the case in the book example. This code is the one that should be used:

db.countries.find( { ‘exports.foods.name’ : { $ne : ‘burgers’ } }, { _id: 0, name : 1 } )

2011-12-31
231TYPO

“is an important selection criteria” should be “is an important selection criterion”. Wrong case.

2011-12-29
226TYPO

“Event smaller scope concerns, such as the existence of bulk data loaders” - should be “Even smaller”

2011-12-29
31TYPO

The notice when creating the stored procedure `log_event` is ‘Someone just changed #%’ but the example run shows “NOTICE: You just changed event …”

2011-12-31
170TYPO

The query by location has the latitude and longitude swapped, so it returns nothing.

The command should be:
db.runCommand({geoNear : ‘cities’, near : [45.52, –122.67], num : 5, maxDistance : 1})

2011-12-29
170ERROR

In MongoDB 2.0.2, $near is no longer supported. Running
db.cities.find({ location : { $near : [–122.67, 45.52] } }).limit(5)
produces
error: { “$err” : “use geoNear command rather than $near query”, “code” : 13501 }

2011-12-31
171TYPO

There is a pair of tags that should not appear here:
$ mongofiles -h localhost:27020 list


connected to: localhost:27020

should be
$ mongofiles -h localhost:27020 list
connected to: localhost:27020

2011-12-29
88ERROR

The query for ‘breed:shepherd’ returns no results. The default analyzer (Whitespace Analyzer) is case sensitive. The query ‘breed:Shepherd’ with capital ‘S’ succeeds.

2011-12-31
200TYPO

(2nd try as the first time I put the URL which were blocked by the spam filter)

The URL for the index on relationship still contains the word node instead of relationship

The path /db/data/index/node/published/date/1916-11-28 should be
/db/data/index/relationship/published/date/1916-11-28

2011-12-31
203ERROR

With Neo4j 1.5, the code for costars does not work. It seems outV does not accept a filter expression.

The expression that worked (for me) is
{_().sideEffect{start = it}.outE(‘ACTED_IN’).inV.inE(‘ACTED_IN’).outV.filter{!start.equals(it)}.uniqueObject } (based on the current version of User-Defined-Steps on the Gremlin Wiki)

2011-12-31
43TYPO

The term inverted index may sounds familiar to you if you’ve ever used a search engine like Lucene or Sphinx.

Should be:
The term inverted index may sound familiar to you if you’ve ever used a search engine like Lucene or Sphinx.

2012-01-09
215TYPO

The two commands for the backup (full and incremental) of Neo4j have different names for the backup directory name. Both names should be identical as the incremental backup should update the full backup

2012-01-09
212ERROR

The property name ha.zoo_keeper_servers is incorrect: at least with version 1.5 (which is the book version), the correct property is ha.coordinators.

Using the wrong name seems to work, but updates to master are never pulled by slaves, and writes to slaves over ReST are not possible.

2012-01-25
216ERROR

The commit 480256bfff036784dc82897d2348a16e3fbf6c03 to the neo4j enterprise project on Github removes the mention of a read-only slave and explicitly states that slaves can be written to, so it is not clear that there is anything like a read-only slave (at least, where the read-only is enforced by Neo4j). The exercise about the setup of read-only slaves should probably be dropped.

2012-01-25
11TYPO

Misspelled: terrabytes

2012-01-09
150TYPO

GeoSpacial.
I assume this is supposed to be GeoSpatial.

2012-01-09
9TYPO

“flexability” should be “flexibility”

2012-01-09
92TYPO

Unfinished sentence:
“you can also try your hand at communicating via Protobuf, which .”

2012-01-09
5TYPO

Duplication of word and in “Relational database management systems (RDBMS) are
set-theory-based systems implemented as two-dimensional tables with rows
and and columns.” (Para. 5 line 4)

2012-01-09
204TYPO

“costar’s costar’s”

The author is unable to use the apostrophe and just stuffs them in at random. Please get a copy editor on the case!

Or see Oatmeal’s cartoon on how to use the apostrophe.

2012-01-09
20wTYPO

“find’s” -> “finds”

2012-01-09
17SUGGEST

This update statement:

UPDATE cities SET postal_code = ‘97205’ WHERE name = ‘Portland’;

…will update all cities with the name ‘Portland’, regardless of country. I know in this case it won’t update more than one row because we only have one row in the table. However, in real life, it is good practice to use the full primary key in the WHERE clause when you want to make sure that you only update ONE row.

Suggestion:

UPDATE cities SET postal_code = ‘97205’ WHERE name = ‘Portland’ AND country_code = ‘us’;

2012-01-25If you look closely, you'll see that the primary key is (country_code, postal_code). We're not updating by the primary key at all, but rather the city name. I didn't want to add undue complexity to a toy example. This example doesn't even contain states, which woud be a problem if we wanted Portland Maine. \n \nThanks for all your suggestions!
36SUGGEST

Under the Day 2 Homework in the PostgreSQL chapter, I have trouble understanding what you want with the following statement:

“Build a pivot table that returns a month, where each week of the month is a row.”

Which month do you want returned? The name of the current month? The number of the current month?

So, there should be only one column (category)?

So, there should be 4-5 rows?

What data should be presented in the rows? No data?

Or are you actually looking for a standard calendar? Like this?

January 2012

week | Mon | Tue | Wed | Thur| Fri | Sat | Sun
————————+————————
1 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2 | 8 | 9 | 10 | 11 | 12 | 13 | 14
3 | 15 | 16 | 17 | 18 | 19 | 20 | 21
4 | 22 | 23 | 24 | 25 | 26 | 27 | 28
5 | 29 | 30 | 31 | | | |

It would be helpful if you explained what you want a bit better. Perhaps even give the printout that you want.

2012-01-25
223TYPO

Redis should be pushing to ‘eric:visited’ not ‘eric:wishlist’

It might also help to say that

redis = Redis.new

using the redis-rb gem

redis.multi do
site = redis.rpop(‘eric:wishlist’)
redis.lpush(‘eric:wishlist’, site)
end

2012-01-25
221221TYPO

It’s can be => It can be

2012-01-25
13TYPO

“CRUD is a useful nemonic” -> “CRUD is a useful mnemonic”

It’s in the callout box at the top of the page explaining the background of the ‘CRUD’ er… mnemonic :)

2012-01-25
13SUGGEST

“”"
Each table also needs to nominate a
unique identifier column to pinpoint specific rows.
“”"

I’d say it can nominate… not that it needs to.

Of course for your example it might? So sorry if I got the wrong end of the stick.

2012-01-25
27TYPO

“However, it’s woth learn the”
=>
“However, it’s worth learning the”

2012-01-25
226ERROR

The ZRANGE error returns elements in the sorted position range, so the first invocation of ZRANGE should be

redis 127.0.0.1:6379> ZRANGE visits 0 –1
1) “gog”
2) “7wks”
3) “prag”

The book instead lists the values by order of insert.

From the doc: “Returns the specified range of elements in the sorted set stored at key.”

2012-01-25Interesting. I actually pasted those results from my own console, so it looks like something must have changed in 2.4. Fixed, thanks.
226ERROR

ZREVRANGE invocation example output has the same problem as the ZRANGE invocation: it lists elements by order of insertion, whereas the actual command lists them by order of score.

From the doc: “Returns the specified range of elements in the sorted set stored at key. The elements are considered to be ordered from the highest to the lowest score”

So the actual output should be

redis 127.0.0.1:6379> ZREVRANGE visits 0 –1 WITHSCORES
1) “prag”
2) “10000”
3) “7wks”
4) “500”
5) “gog”
6) “9”

2012-01-25
60SUGGEST

I installed RubyGems, but in order to get the Ruby program to work, I also needed to:

sudo gem install json

(Otherwise I got this:

/usr/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:36:in `gem_original_require’: no such file to load — json (LoadError)

)

You may want to add that as a requirement.

2012-01-25
66TYPO

Suggestion: Put a space between “else”
and “totals”, otherwise readers will get:

ReferenceError: elsetotals is not defined

…when copying the code from the pdf document.

2012-01-25I'm not sure what do do here, there are several spaces, when I copy: \n else totals[style] = v[i][style]; \n
61ERROR

I think the sums in the reduce function should be initialized with a count of 0 , instead of 1 - like so:

reduce = function(mappedVals) {
var sums = {count : 0};
for (var i in mappedVals) {
sums[count] += mappedVals[i][count];
}
return [sums];
}

Otherwise the result will always be of by one.

2012-01-25
294TYPO

“seperate thread”

There’s “a rat” in “separate”.

2012-01-31
21ERROR

“PostgreSQL automatically creates an index on the primary key. This is usually a hash index (like a hashtable, or a map), where the key is the primary key value, and the value points to a row on disk, as shown in Figure 6, An indexed lookup points to an exact row without a scan, on page 22. Using the UNIQUE keyword is another way to force a hash index on a table column.”

This is wrong. The default index type is B Tree in all current implementations of Postgres. Unique does not create a hash, like all other indexes it creates a B Tree by default; however, unlike other explicit indexes unique must create a B Tree and in turn only B Trees can be conditioned unique.

See the following all at postgresql (dot) org:
/docs/current/interactive/indexes-unique.html
/docs/current/interactive/sql-createindex.html
/docs/current/interactive/sql-altertable.html

The different indexing methods are one of PostgreSQL’s cool mid-level features and a more detailed discussion would be really great. Hash is small and fast but only does equality. B Tree is everything else. The GIS index is unique to Postgres as far as I know and quite cool.

2012-01-31
297TYPO

The MULTI command is spelled MUTI in the code sample. It should be
MULTI
SMEMBERS “artist:Beatles:John Lennon”
SMEMBERS “artist:Beatles:Ringo Starr”
EXEC

2012-02-07
133TYPO

You client is responsible…

should be

Your client

2012-02-12
136TYPO

However the Riak team is working on these fairly minor hickup.

should be

…hiccups.

2012-02-12
136TYPO

Sentence starting with
“How it dances around the problem…” is a run on. Perhaps the comma before “Riak leverages” should be a period.

2012-02-12
136TYPO

“If you want to scale out …, take it look.” should be “, take a look.”

2012-02-12
35SUGGEST

The section on crosstab() isn’t all that clear. It would be great if you had a bit more illustration of how pivot tables / crosstab work(s). Even something as simple as rowsandcolumns.blogspot.com/2011/10/postgresql-crosstab-query-rotate-table.html would be helpful.

2012-04-10
59SUGGEST

The Riak link walking section is unclear. when you explain the link walking URL spec the function of the underscore slots needs to be explained up front, even something as simple as ,, would do it.

Also the example of the links you are setting is good but unclear. The problem is that what you are trying to accomplish is never really stated anywhere. Instead the reader is left to figure out what you are trying to accomplish while reading the headers to accomplish it. A single figure like that in basho.com/blog/technical/2010/02/24/link-walking-by-example/ showing the final state of the links you create would make it much clearer.

2012-04-10
64ERROR

The official Riak Ruby driver is no longer called “Ripple”

“Ruby client for Riak (previously known as ”ripple/riak-client“)” from the Basho repo at: github.com/basho/riak-ruby-client

2012-02-14Wow, things move so fast! updated, thanks.
75ERROR

The discussion of vnodes is systemically wrong. The vnode concept is a way to partition the ring evenly across a variable number of physical nodes. N/W/R are not sensitive to vnode, they are sensitive to physical nodes.

With multiple vnodes on a single physical node if N/W/R referred to vnodes and a W=3 write could land on a single physical node then you’d have no replication in your cluster, likewise a consensus read could fail if a single physical node was down in a cluster of 3 or more nodes.

see wiki.basho.com/Concepts.html

2012-02-14
70TYPO

[“rooms”,“102”],[“rooms”,“102”],[“rooms”,“103”] should be
[“rooms”,“101”],[“rooms”,“102”],[“rooms”,“103”]

2012-03-22
68SUGGEST

The figure 13 is is the middle of the json code - uneasy to copy/paste !

2012-03-22
293TYPO

Top sentence currently reads:

It’s also
highly configurable, with many durability and replication settings the conform to whatever your needs may be.

Should change “the” to “that” to read:

It’s also
highly configurable, with many durability and replication settings that conform to whatever your needs may be.

2012-03-22
289TYPO

Remove “a” from the sentence: Bridging between two or more servers only requires a some minor changes to our existing ISBN client.

2012-03-22
246TYPO

Sentence currently reads:
Then we’ll create the costars custom step the following code.
Change to “with the” or “in the”

2012-03-22
243SUGGEST

Neo4j Indexing question.

After reading the second and third paragraph on p243, I’m left to believe that one must manually add every single value to an index in Neo4j. Is that true? If so, does this basically mean that you must modify your programs to manually populate every index value as your create or change the real value?

If this is the case, and it seems a little crazy if it is, it might be worth another paragraph to explain it. If it isn’t, some clarification here might be needed.

2012-04-10It does sound a little crazy, and yes this is how it works. Thanks for the comment.
173TYPO

Sentence currently reads:
But in the meantime, to query a the sharded cities collection for other cities near a location, use the geoNear() command.

Should remove “a” to be “query the sharded cities”.

2012-03-22
189TYPO

sentence reads: As we’ve done with other databases, we’ll some import structured data and then use it to explore some advanced concepts.

change to: As we’ve done with other databases, we’ll import some structured data and then use it to explore some advanced concepts.

2012-03-22
24ERROR

Shouldn’t “HAVING count(*) >= 2” in the query limit results to those where count >= 2?

2012-03-22
53TYPO

Typo in first line - should be ‘steel beam’

2012-03-22
64TYPO

typo in last paragraph - ‘install the Riak Riak driver’

2012-03-22
138TYPO

‘try mongodb.org’s own apt-get distro’ - a better term than ‘distro’ might be ‘package’, or ‘channel’

2012-03-22
145TYPO

typo in heading - should be ‘elemMatch’ instead of ‘eleMatch’

2012-03-22
156TYPO

‘The millis value chnaged’ - should be ‘changed’

2012-03-22
142SUGGEST

Clarification on where the insertCity function goes - do we just type it into the shell, or do we put it in a file and then load that into the shell?

2012-03-22
57ERROR

If following the guide verbatim there will be two buckets listed from localhost:8091/riak?buckets=true - {“buckets’:[”favs“,”animals"]} !

2012-03-22
106TYPO

There’s a grammatical error in third sentence of the first paragraph of Chapter 4. The sentence begins with, “If you data is not measured the high Gigabytes or larger…”. It should reworded to, “If your data is not measured in the high gigabytes or larger…”

2012-03-22
3326ERROR

“HAVING count(*) >= 2….” and the results table shows results having count = 1.

This is, of course in error, as items with count = 1 doesn’t meet the described criteria, count >= 2.

Thanks!

2012-03-22
223TYPO

“comes equipped with with” pro “comes equipped with”

2012-03-22
223TYPO

“Launch a web browsers” pro “Launch a web browser”

2012-03-22
180TYPO

In the last paragraph of section 6.1, there’s a phrase that reads, “… we’ll some import structured data…”. It should read, “… we’ll import some structured data …” (flipped the word “some” and “import”).

2012-03-22
299ERROR

The error is not in the book, but in the code populate_couch.js: line 51
if(totalBands < processedBands) {
should be
if(totalBands <= processedBands) {
otherwise the process does not complete and has to be killed.

2012-03-22
303ERROR

The code shown on the page (or downloaded from the website) does not run in node.js (lines 114 and 115):
membersQuery = ‘g.V[[name:“‘bandName’”]]’,
membersQuery += ‘.out(“member”).in(“member”).uniqueObject.name’;
should be
membersQuery = ‘g.V[[name:“‘bandName’”]]’
+ ‘.out(“member”).in(“member”).uniqueObject.name’;
(the comma at the end of line 114 cannot be followed by an update instructions; either it should be a semi-colon, or the two lines rewritten as above).

Also, the Gremlin queries are not working in any recent version of Neo4j due to significant changes in Gremlin (on Neo4j 1.6.1, this is what I use:
membersQuery = ‘g.idx(“bands”)[name]’
+ ‘.out(“member”).in(“member”).dedup.name’;
)

2012-03-22
82TYPO

Second paragraph of Day 3: … Riak as a distributed file system using Luwak.

Actually there is no mention of Luwak in this chapter (beside the one above). Furthermore Luwak has been deprecated in Riak 1.1 and is no longer available in recent downloads.

2012-03-22
306SUGGEST

Day 3 Homework 2:
“Alter the CouchDB/Neo4j synchronizer to also track an artist’s bands. Build a Neo4j query in the bands.js script that retrieve’s all bands an artist has performed on—list those bands.”

The data is already loaded in Neo4j, and the default bands.js already list all the bands an artist has played on. So either the exercise needs a clarification as to what exactly is required, or perhaps a different exercise is needed.

2012-03-22
306SUGGEST

Homework 3:
“Add Riak into the mix, by storing a few music samples into Luwak, whereby users can hear a song or two related to a band. If any songs exists for a band, add a link to the webapp. Ensure the Riak data and Couch remain in sync.”

Luwak is deprecated, and Riak does not seem to have any replacement for it.

Perhaps the exercise should require MongoDB and GridFS instead?

2012-03-22
87SUGGEST

The validator function that we are creating is called good_scope.. However, it is validating that the score value is within a given range. Is that a typo? Should it actually be good_score?

2012-03-22
87TYPO

In the Java script method good_scope, a semi colon is missing after the return statement in the catch.

Also, the JSON.parse method appears to have extra [] on the values call: object.values[[0]].data.

2012-03-22
247TYPO

In the section called “Of Course Kevin Bacon”, there’s a sentence that reads, “We’ll use the costars step we created yesterday.” It should read, “We’ll use the costars step we just created.”, since in the most recent version of the PDF, the `costars` step was created just one page prior and on the same day.

2012-03-22
68TYPO

Figure shows a value of $37 in 2nd group of node C, however the line above shows a different value of 98. $37 should become $98 for consistency.

2012-03-23
91TYPO

Orthogonal is spelled wrong:

“This is actually a powerful feature, since it allows us to index data orthoginal to any data we may store.”

2012-03-22
91SUGGEST

The book explains how to set up a secondary index for Blue II, however there is no example on how to then query on the index.

Looking at the Basho wiki, I determined that I could do:

curl http colon //localhost:8091/buckets/animals/index/mascot_bin/butler

to retrieve the key related to the secondary index.

All of the other places where we put some data into the store has examples on how to get it back out. It might be handy to show something for using the secondary index as well.

2012-03-22
277ERROR

The last sentence of the Day1 of the Redis section says, “And finally, we saw how you can control durability by storing these keys to disk.” As far as I can tell durability was only covered during Day2 and not Day1.

2012-03-22
85TYPO

Jane’s job now it to use this information to…

2012-04-11
56TYPO

Using a Mac with Postgres 9.1.3.

Twice near the bottom of the page there are SQL queries that have & instead of & in them.

WHERE to_tsvector(title) @@ to_tsquery(‘english’, ‘night & day’);
should be
WHERE to_tsvector(title) @@ to_tsquery(‘english’, ‘night & day’);

SELECT to_tsvector(‘A Hard Day’‘s Night’), to_tsquery(‘english’, ‘night & day’);
should be
SELECT to_tsvector(‘A Hard Day’‘s Night’), to_tsquery(‘english’, ‘night & day’);

2012-08-02Eesh... formatting error! Thanks for catching that, I'll get this fixed.
45ERROR

When combining the metaphone search and ordering by Levenshtein distance, I believe the results shown are incorrect. I get the results show below, correctly sorted as the Levenshtein distance from “Robin Williams” to “Robin Williams” is 0, and should be the first result in the list. Robin Williams cannot rank #3 if the sort is done correctly. I’m using Postgres 9.1.3 on Mac.

book=# select * from actors where metaphone(name,8) % metaphone(‘Robin Williams’,8)
book-# order by levenshtein(lower(‘Robin Williams’),lower(name));
actor_id | name
—————+————————-
4093 | Robin Williams
2442 | John Williams
4479 | Steven Williams
4090 | Robin Shou
(4 rows)

2012-08-02You are correct, thanks for the heads up. I'll get this fixed for the next release.
271ERROR

Under Neo4j’s Weaknesses its stated that “Edges in Neo4j cannot direct a vertex back on itself.” As I read it, that would say that a node cannot have relationships with itself.

In practice it works, and it’s also mentioned in the Docs: docs.neo4j.org/annotated/#graphdb-neo4j-relationships

Its possible I’m misreading it, graph theory isn’t my thing :)

2012-08-02
11%ERROR

Maybe it is late at night and I haven’t been paying attention but the summary for day 2 of postgres mentions learning that you can store weird datatypes like arrays, but I don’t remember seeing that anywhere in the chapter. I even quickly paged back to the start of the chapter of day 2 to see if I had missed it, but didn’t find it.

2012-08-02If you look on page 30, we add an array of colors to the events table. \n \nALTER TABLE events \nADD colors text ARRAY; \n \nThanks!
140TYPO

When using the insertCity JS function, the dates entered are in YYYY-DD-MM format rather than YYYY-MM-DD. The ISODate happily takes this and adds the appropriate number of months, so ‘2008-31-01’ becomes ‘2010-07-01’. However, the output at the end of page 140 shows the date as was intended, ‘2008-01-31’.

2012-08-02
64SUGGEST

3rd para, js code:

The reduce function is a little bit complicated

looping:
var sums = {count : 0};
for (var i in mappedVals) {
sums[count] += mappedVals[i][count];
…
return [sums];

clearly
var sums = 0;
adapt loop;
…
return[{count: sums}];

is simpler.

2012-08-02
64SUGGEST

para 5, ruby code

this is not idiomatic Ruby and bad Active Record, may I humbly suggest the following improvement:

capacity_by_style = Hash.new{ |h, k| h[k]=0 }
Room.find_each do |room| # all and then each is really bad
# wouldn’t consider it fair to AR
# in this context
capacity_by_style[ room.style ] += room.capacity
end

2012-08-02
34ERROR

The PostgreSQL documentation for crosstab indicates that the source query “should always specify ORDER BY 1,2 to ensure that the input rows are properly ordered” (see www.postgresql.org/docs/9.1/static/tablefunc.html).

The query supplied on Page 34 doesn’t do this, and so can give unexpected results. For me it was fine until I added extra events as suggested in the text. e.g.:

SELECT * FROM crosstab(‘SELECT extract(year FROM starts) AS year, extract(month FROM starts) AS month, count() FROM events GROUP BY year, month’, ’SELECT FROM month_count’) AS (year int, jan int, feb int, mar int, apr int, may int, jun int, jul int, aug int, sep int, oct int, nov int, dec int); year | jan | feb | mar | apr | may | jun | jul | aug | sep | oct | nov | dec
———————————+————————————+————
2012 | | | 1 | | | | | | | | |
2013 | | 1 | | | | | | | | | |
2012 | | 5 | | 1 | 1 | | | | | | | 1
(3 rows)

where it should be:

SELECT * FROM crosstab(‘SELECT extract(year FROM starts) AS year, extract(month FROM starts) AS month, count() FROM events GROUP BY year, month ORDER BY year, month’, ’SELECT FROM month_count’) AS (year int, jan int, feb int, mar int, apr int, may int, jun int, jul int, aug int, sep int, oct int, nov int, dec int);
year | jan | feb | mar | apr | may | jun | jul | aug | sep | oct | nov | dec
———————————+————————————+————
2012 | | 5 | 1 | 1 | 1 | | | | | | | 1
2013 | | 1 | | | | | | | | | |
(2 rows)

2012-08-02Thank you, that's an excellent point! I'll certainly add this info into the next update.
39TYPO

Nit-picking I know, and nobody would be confused by it, but the query should be:

SELECT title FROM movies WHERE title % ‘Avatre’;

not

SELECT * FROM movies WHERE title % ‘Avatre’;

to get the results shown.

2012-08-02There are few things worth picking as nits. Thank you, I'll get this fixed in the next update.
43TYPO

Broos Wlis in the first 2 queries becomes Broos Wils in the 3rd. If you swap the 3rd query to Broos Wlis it doesn’t work, so I’d suggest using Broos Wils everywhere.

2012-08-02You noticed I accidentally transposed l and i? You have excellent i's (hah). Thanks, I'll get this fixed for the next version.
61TYPO

In the curl command for the PUT of polly-image.jpg, the Content-Type header is misspelled as Content-type.

2012-08-02Actually, HTTP headers are case insensitive. \n \nAh, I see you noticed that yourself! Thanks
82TYPO

The curl example for when Jane and Rakshith both pull Bruiser’s data has a URL which includes a return_body parameter. I don’t think that’s a valid option on an object fetch (it would make sense on a store object request).

(Please forgive the typo report I made before this one. I’ve since learned that HTTP header names are case-insensitive. Sorry for the noise.)

2012-08-02
261TYPO

Where is page 261? Chapter 7 ends on page 259, then Redis starts (presumably) on page 260, but the next page is 262…

2012-08-02I don't think this is a real problem. Probably just a blank page that didn't make it into the ebook.
140ERROR

The book says that “You can just paste the code into the shell”

However, i had to use something like the following to get this to work

> db.system.js.save( { _id: “insertCity”, value: function(name, population, last_census, famous_for, mayor_info) {
… db.towns.insert({name:name, population:population, last_census:last_census, famous_for:famous_for, mayor_info:mayor_info});
… }});
> db.eval(“insertCity(‘Pune’,1200,‘2012-01-01’,[‘shaniwarwada’],{name:‘Ravi Kumar’,party:‘D’})”)
null
> db.towns.find()
{ “_id” : ObjectId(“5018de9e521b28cdc63db271”), “name” : “New York”, “population” : 22, “last_census” : ISODate(“2012-01-01T00:00:00Z”), “famous_for” : [ “times square”, “manhattan” ], “mayor” : { “name” : “Michael Bloomberg”, “party” : “I” } }
{ “_id” : ObjectId(“50190b0fe1a47948c79fb0f7”), “name” : “Pune”, “population” : 1200, “last_census” : “2012-01-01”, “famous_for” : [ “shaniwarwada” ], “mayor_info” : { “name” : “Ravi Kumar”, “party” : “D” } }

2012-08-02Works for me. I downloaded the latest stable build for Mac OSX and ran the insertCity function exactly as it appears in the PDF---no problems. :/
23TYPO

The output of the aggregate query on the bottom half of the page “SELECT venue_id FROM events GROUP BY venue_id HAVING count(*) >=2 AND venue_id IS NOT NULL;” shows two columns in the results (venue_id, count) when only the venue_id was actually selected in the query.

282TYPO

The book states:
"…low and high range numbers are inclusive by default…So, this will return all scores where 9 <= score <= 10,000:

redis 127.0.0.1:6379> ZRANGEBYSCORE visits 9 9999"

The description saying that it is <= 10,000 should be either <= 9999 or < 10,000 (the former would probably work better in the given context)

158145TYPO

On page 158 (pdf) there is this following quote :

“Boolean Ops
So far, all of our criteria are implicitly and operations.”

But on the previous page (#157 pdf), there is an example as follows :

“db.countries.find(
{ ‘exports.foods.name’ : ‘bacon’, ‘exports.foods.tasty’ : true }, { _id : 0, name : 1 }
)”

Result :

{ “name” : “United States” }
{ “name” : “Canada” }

This looks like more like an OR operation than an AND operation.

26/27ERROR

Using the function input parameters ‘title’, ‘starts’ and ‘ends’ leads to following error:

psql:add_event.sql:25: ERROR: syntax error at or near “$1”
LINE 1: INSERT INTO events ( $1 , $2 , $3 , venue_id) VALUES ( $1 …

changing the parameter names to something else, for example:
CREATE OR REPLACE FUNCTION add_event( i_title text, i_starts timestamp,
i_ends timestamp, …

and adjusting the INSERT statement:
INSERT INTO events (i_title, i_starts, i_ends, venue_id) VALUES (title, starts, ends, the_venue_id);

would help

postgres version: postgresql-server-8.4.12-1.el6_2.x86_64

154TYPO

The sentence that describes the entry in the system.profile collection says “info is a string description of the operation”. I don’t see a field named info, and none of the fields appear to be a string description of the operation.

156ERROR

The output of the first group command doesn’t match what I get. The text has:

[ { “800” : 50000, “855” : 50000 } ]

while I get:

[
\t{
\t\t“components.area” : 800,
\t\t“count” : 50000
\t},
\t{
\t\t“components.area” : 855,
\t\t“count” : 50000
\t}
]

Maybe it’s a version difference (I’m using v2.0.4), but it seems like a significant one. I have to do some extra work with a finalizer to get the output in the text:

db.phones.group({
initial: { count:0 },
reduce: function(phone, output) { output.count; },
cond: { ‘components.number’: { $gt : 5599999 } },
key: { ‘components.area’ : true },
finalize: function(out) {
retval = {};
retval[out[‘components.area’]] = out.count;
return retval;
}
})

158TYPO

The update_area function from mongo/update_area.js is broken. The line that applies the update reads

db.phone.update…

when it should be

db.phones.update…

It seems that Spelling Bee Warning wasn’t enough :-)

30TYPO

The last sentence on the page says “Now it’s a matter of setting an array OR color strings…” when it should say “Now it’s a matter of setting an array OF color strings…” Just a typo.

18ERROR

Figure 2: it seems countries => cities relationship should have cardinality “zero or many” rather than “one or more”. At least the database doesn’t enforce the “one or more”, and in fact, it would be pretty annoying if it did since then we wouldn’t be able to add a country until we have a city.

Exactly the same comment applies to the cities => venues relationship.

19ERROR

I don’t think Postgres will create an implicit index on the column(s) of the table that is the target of REFERENCES keyword. From the official docs on CREATE TABLE: “The referenced columns must be the columns of a non-deferrable unique or primary key constraint in the referenced table.” This suggests that the referenced columns must already be indexed; if they weren’t, the constraint will presumably fail. An index on the column in the current table is also not created.

224TYPO

Figure 34 has riesling misspelled as reisling.

235TYPO

…this new step should attach to both Vertex and Pipe classes (when in double, just use both)…

Should that be “when in doubt, just use both”?

86SUGGEST

After enabling riak_search and configuring the pre-commit hook on the bucket, you need to restart the servers before trying to add any more data to the bucket, otherwise the pre-commit hook fails with an error. Might be nice to advise readers of the need to restart the servers.

89TYPO

The examples for the secondary index are against a server running on port 8098 rather than ports 8091-8093, on which the reader is running Riak nodes. Whilst the intention may not be for the reader to run these examples, and it’s a simple substitution to make them work, it would be nice to keep the port numbers consistent.

247TYPO

“and a count to set a maximum number or loops.” should probably be “and a count to set a maximum number of loops.”

248TYPO

The example creates a scorer

barycenter = new BarycenterScorer<Vertex,Edge>( j, t )

then later:

bacon.costars.each{
score = b.getVertexScore(it);

That should probably be:

bacon.costars.each{
score = barycenter.getVertexScore(it);

(or maybe call the scorer b in the first place…)

266ERROR

When I try the RPUSH command in the redis cli, it doesn’t return the number of values pushed. It returns the length of the list. So “RPUSH eric:wishlist 7wks” returns (integer) 1, but another “RPUSH eric:wishlist gog” returns (integer) 2.

53ERROR

The riak-admin join command is now deprecated: riak-admin cluster join dev2@127.0.0.1 appears to be the equivalent

27ERROR

The INSERT INTO events(title, starts, ends, venue_id) gave a syntax error. I’m not familiar with the language, but I suspect that the insert parameters may not be the same as the formal parameters of the procedure, since when I changed that to vtitle, vstarts etc. it seemed to work.

27SUGGEST

There is probably some way that I could have prevented this, but if event_id is not present in the insert, I get ‘duplicate value violates unique constraint “events_pkey”’
Maybe there should be some “auto increment” at the creation of the events table on page 17.

40TYPO

There is an & where there should be just an &
(html error?)

67ERROR

changing “inputs” to “rooms” gives me error preflist exhausted. Could be my machine, could be settings, but is not very insightful.

58ERROR

It may be a version problem, but the , doesn’t seem to work in the Link here. I got an “empty” response from the server as is. I tried
-H “Link:;riaktag=\\”contains\\“” \\
-H “Link:;riaktag=\\”next_to\\“” \\

instead and that seems to do the trick. As I’m trying to LEARN riak from this text, I have no idea why.

61TYPO

In the “Since we” paragraph, shouldn’t “You link the direction” be “You link in the direction”? (I have several more picky ones like that…)

99SUGGEST

“adding ‘Welcome to the wiki!’ to the column called ‘text:’.”

At first I thought “but you just said that text is a column family, not a column. ” On page 101 we learn that a qualifier can be an empty string, so I guess “text:” is a column family with a qualifier, but for someone just learning HBase, the description on page 99 is very confusing.

149TYPO

“your city or meant to querying on” (“query on”)

232TYPO

“loop() invokes the given in the closure” (invokes the code given in the closure?)

245SUGGEST

“We didn’t know who Roddy McDowall was” I hope you’ve remedied that! You can be forgiven for not knowing that he was one of the lesser known but cooler Batman villains (see www.youtube.com/watch?v=h9RKjmhtVAM) but there’s no excuse for not having seen the first Planet of the Apes movie—the 1968 one.

52SUGGEST

“Erlang is also required to run Riak.” Some readers will have no clue what Erlang is, so add a few words here to help them.

140ERROR

Example census dates are in the wrong format.

They should be entered as “2008-01-31” and “2007-09-20” (ISO format) instead of “2008-31-01” and “2007-20-09”.

Javasript being javascript, it won’t complain and the inserted data will be wrong.

324ERROR

script “node populate_couch.js” throws error: http.createClient is deprecated

284ERROR

The dataset for running isbn.rb (isbn.tsv) is not in the code downloads.

66ffERROR

Several nodes are started and used to build a Riak ring. However, to actually make the nodes a cluster some commands are missing:
bin/riak-admin cluster plan
bin/riak-admin cluster commit
See http docs.basho.com/riak/latest/cookbooks/Basic-Cluster-Setup/

142ERROR

The ‘find’ query in the first half of the page has an error: the date should be ISODate(‘2008-01-31’) and not ISODate(‘2008-31-01’) (month and day numbers are swapped). The system didn’t warn me that the date was invalid! I just realized this because the query results were not the expected ones!

210198ERROR

Hello,

The second cURL call has an extra backslash on the second line. Once I took it out the code worked just fine:

Note: I had pasted the original and fixed curl code, but your submission system gave me an error saying that hyperlinks are not allowed. Here is a shortened version to get the point across:

Original:
…by_name?\\
limit=5\\&startkey=%22C%22

Fixed:
…by_name?\\
limit=5&startkey=%22C%22

Regards,

233TYPO

“We can preform…” should be “we can perform…”

223ERROR

It seems that the makers of Neo4j no longer let their browser support gremlin. There is some technical doc on “not allowed hyperling, referring to grokbase”, but it leaves this part of the book rather useless.

27ERROR

On code postgres/add_event.sql you declare variable called found_count but it is never used in the function. It is hard for the reader to know if it is a leftover variable or does it have some meaning outside the function.

53SUGGEST

The join command has been deprecated in favor of clustering commands provided by riak-admin cluster.

54SUGGEST

Ports have changed to 10018. It is better to look at the config file, which is now called riak.conf by the way first.

107SUGGEST

shout text = String.toUpper text
whisper text = String.toLower text

surely

shout = String.toUpper
whisper = String.toLower

is preferable

64ERROR

My version in the book says August 2012 P2.0 but it wasn’t an option. Not sure if this has been reported or not. But the reduce function on pg 64 currently reads:

reduce = function(mappedVals) {
var sum = 0;
for (var i in mappedVals) {
sum += mappedVals[i][count];
}
return [{count:sum}];
}

The 4th line should read:
sum += mappedVals[i].count;

29ERROR

createlang is depricated

Categories: