Database Reference
In-Depth Information
def assemble(comments, map)
list = []
comments.each do |comment|
list.push(comment)
child_comments = map[comment['_id'].to_s]
if child_comments
list.concat(assemble(child_comments, map))
end
end
list
end
To p r i n t t h e c o m m e n t s , y o u m e r e l y i t e ra t e o v e r t h e l i s t , i n d e n t i n g a p p r o p r i a t e l y f o r
each comment's
depth
:
def print_threaded_list(cursor, opts={})
threaded_list(cursor, opts).each do |item|
indent = " " * item['depth']
puts indent + item['body'] + " #{item['path']}"
end
end
Querying for the comments and printing them is then straightforward:
cursor = @comments.find.sort("created")
print_threaded_list(cursor)
B.1.5
Worker queues
You can implement worker queues in MongoDB using either standard or capped col-
lections. In both cases, the
findAndModify
command will permit you to process queue
entries atomically.
A queue entry requires a
state
and a
timestamp
plus any remaining fields to con-
tain the payload. The state can be encoded as a string, but an integer is more space-
efficient. We'll use 0 and 1 to indicate
processed
and
unprocessed
, respectively. The time-
stamp is the standard
BSON
date. And the payload here is a simple plaintext message,
but could be anything in principle:
{ state: 0,
created: ISODate("2011-02-24T16:29:36.697Z"),
message: "hello world" }
You'll need to declare an index that allows you to efficiently fetch the oldest unpro-
cessed entry (
FIFO
). A compound index on
state
and
created
fits the bill:
db.queue.ensureIndex({state: 1, created: 1})
You then use
findAndModify
to return the next entry and mark it as processed:
q = {state: 0}
s = {created: 1}
u = {$set: {state: 1}}
db.queue.findAndModify({query: q, sort: s, update: u})