これは、集計フレームワークでこの問題を解決しようとしたこの質問のフォローアップです。残念ながら、この特定の mongodb インストールを集約フレームワークを含むバージョンに更新できるようになるまで待つ必要があるため、このかなり単純なピボット操作に MapReduce を使用する必要がありました。
複数の毎日のダンプを含む、以下の形式の入力データがあります。
"_id" : "daily_dump_2013-05-23",
"authors_who_sold_books" : [
{
"id" : "Charles Dickens",
"original_stock" : 253,
"customers" : [
{
"time_bought" : 1368627290,
"customer_id" : 9715923
}
]
},
{
"id" : "JRR Tolkien",
"original_stock" : 24,
"customers" : [
{
"date_bought" : 1368540890,
"customer_id" : 9872345
},
{
"date_bought" : 1368537290,
"customer_id" : 9163893
}
]
}
]
}
次の形式で出力した後、すべての毎日のダンプで各 (一意の) 作成者のすべてのインスタンスを集計します。
{
"_id" : "Charles Dickens",
"original_stock" : 253,
"customers" : [
{
"date_bought" : 1368627290,
"customer_id" : 9715923
},
{
"date_bought" : 1368622358,
"customer_id" : 9876234
},
etc...
]
}
このマップ関数を作成しました...
function map() {
for (var i in this.authors_who_sold_books)
{
author = this.authors_who_sold_books[i];
emit(author.id, {customers: author.customers, original_stock: author.original_stock, num_sold: 1});
}
}
...そしてこのreduce関数。
function reduce(key, values) {
sum = 0
for (i in values)
{
sum += values[i].customers.length
}
return {num_sold : sum};
}
ただし、これにより次の出力が得られます。
{
"_id" : "Charles Dickens",
"value" : {
"customers" : [
{
"date_bought" : 1368627290,
"customer_id" : 9715923
},
{
"date_bought" : 1368622358,
"customer_id" : 9876234
},
],
"original_stock" : 253,
"num_sold" : 1
}
}
{ "_id" : "JRR Tolkien", "value" : { "num_sold" : 3 } }
{
"_id" : "JK Rowling",
"value" : {
"customers" : [
{
"date_bought" : 1368627290,
"customer_id" : 9715923
},
{
"date_bought" : 1368622358,
"customer_id" : 9876234
},
],
"original_stock" : 183,
"num_sold" : 1
}
}
{ "_id" : "John Grisham", "value" : { "num_sold" : 2 } }
偶数の索引付けされたドキュメントには、customers と original_stock がリストされていますが、num_sold の合計が正しくありません。奇数の索引付けされたドキュメントには num_sold しかリストされていませんが、これは正しい数です。
何が欠けているのか誰か教えてください。