Databases Reference
In-Depth Information
[
{"time" : "10/3/2010 05:00:23 GMT-400", "price" : 4.10},
{"time" : "10/4/2010 11:28:39 GMT-400", "price" : 4.27},
{"time" : "10/6/2010 05:27:58 GMT-400", "price" : 4.30}
]
We can accomplish this by splitting the collection into sets of documents grouped by
day then finding the document with the latest timestamp for each day and adding it to
the result set. The whole function might look something like this:
> db.runCommand({"group" : {
... "ns" : "stocks",
... "key" : "day",
... "initial" : {"time" : 0},
... "$reduce" : function(doc, prev) {
... if (doc.time > prev.time) {
... prev.price = doc.price;
... prev.time = doc.time;
... }
... }}})
Let's break this command down into its component keys:
"ns" : "stocks"
This determines which collection we'll be running the group on.
"key" : "day"
This specifies the key on which to group the documents in the collection. In this
case, that would be the "day" key. All of the documents with a "day" key of a given
value will be grouped together.
"initial" : {"time" : 0}
The first time the reduce function is called for a given group, it will be passed the
initialization document. This same accumulator will be used for each member of
a given group, so any changes made to it can be persisted.
"$reduce" : function(doc, prev) { ... }
This will be called once for each document in the collection. It is passed the current
document and an accumulator document: the result so far for that group. In this
example, we want the reduce function to compare the current document's time
with the accumulator's time. If the current document has a later time, we'll set the
accumulator's day and price to be the current document's values. Remember that
there is a separate accumulator for each group, so there is no need to worry about
different days using the same accumulator.
In the initial statement of the problem, we said that we wanted only the last 30 days
worth of prices. Our current solution is iterating over the entire collection, however.
This is why you can include a "condition" that documents must satisfy in order to be
processed by the group command at all:
> db.runCommand({"group" : {
... "ns" : "stocks",
... "key" : "day",
 
Search WWH ::




Custom Search