按文档中的键汇总总数
Aggregate totals by Keys in a document
我有一个 mapreduce 函数,我想在 mongoDB 中编写这个函数来计算一个角色被玩了多少次。我的 json 中的相关部分如下所示:
"playerInfo": {
"Player 1": {
"info":{
"characterId":17
}
},
"Player 2": {
"info":{
"characterId":20
}
}
}
我想统计每个 "characterId" 在我的文档中存在多少次,有 10 个玩家,从玩家 1 到玩家 10。
两个问题:
1。当我有一个数字作为我的密钥的一部分时,如何在 mongo 中使用 mapreduce。
2。如何在 mapreduce 中连接字符串,以便下方显示的代码正确?
db.LoL.mapReduce( function()
{
for (var i in this.playerInfo)
{
emit(this.playerInfo.'Player '+(i).info.characterId, 1);
}
},
function(keys, values) {
return Array.sum(values)
}, {out: { merge: "map_reduce_example5" } } )
非常感谢您的回答!
所以这里的结构确实有一些问题,你真的 "should" 改变了它
mapReduce
非常简单,因为您可以通过 Object.keys()
迭代键名
db.LoL.mapReduce(
function() {
Object.keys(this.playerInfo).forEach(function(key) {
emit({ "player": key, "characterId": this.playerInfo[key].info.characterId }, 1)
})
},
function(values) { return Array.sum(values) },
{
"query": { "playerInfo": { "$exists": true } }
"out": { "inline": 1 }
}
)
如果您将数据格式更改为使用数组,并使用值而不是命名键来属性:
{
"playerInfo": [
{ "player": "Player 1", "characterId": 17 },
{ "player": "Player 2", "characterId": 20 }
]
}
然后 .aggregate()
方法处理这个要快得多,returns 一个用于大型结果集的游标:
db.collection.aggregate([
{ "$unwind": "$playerInfo" },
{ "$group": {
"_id": "$playerInfo",
"count": { "$sum": 1 }
}}
])
使用 MongoDB 3.4 及更高版本,您甚至可以在现有结构上使用
db.LoL.aggregate([
{ "$project": {
"playerInfo": { "$objectToArray": "$playerInfo" }
}},
{ "$unwind": "$playerInfo" },
{ "$group": {
"_id": {
"player": "$playerInfo.k",
"characterId": "$playerInfo.v.info.characterId"
},
"count": { "$sum": 1 }
}}
])
这与 mapReduce 基本相同,只是由于使用了本机运算符而不是运行速度慢得多的 JavaScript 评估,所以速度要快得多。
我有一个 mapreduce 函数,我想在 mongoDB 中编写这个函数来计算一个角色被玩了多少次。我的 json 中的相关部分如下所示:
"playerInfo": {
"Player 1": {
"info":{
"characterId":17
}
},
"Player 2": {
"info":{
"characterId":20
}
}
}
我想统计每个 "characterId" 在我的文档中存在多少次,有 10 个玩家,从玩家 1 到玩家 10。
两个问题:
1。当我有一个数字作为我的密钥的一部分时,如何在 mongo 中使用 mapreduce。
2。如何在 mapreduce 中连接字符串,以便下方显示的代码正确?
db.LoL.mapReduce( function()
{
for (var i in this.playerInfo)
{
emit(this.playerInfo.'Player '+(i).info.characterId, 1);
}
},
function(keys, values) {
return Array.sum(values)
}, {out: { merge: "map_reduce_example5" } } )
非常感谢您的回答!
所以这里的结构确实有一些问题,你真的 "should" 改变了它
mapReduce
非常简单,因为您可以通过 Object.keys()
db.LoL.mapReduce(
function() {
Object.keys(this.playerInfo).forEach(function(key) {
emit({ "player": key, "characterId": this.playerInfo[key].info.characterId }, 1)
})
},
function(values) { return Array.sum(values) },
{
"query": { "playerInfo": { "$exists": true } }
"out": { "inline": 1 }
}
)
如果您将数据格式更改为使用数组,并使用值而不是命名键来属性:
{
"playerInfo": [
{ "player": "Player 1", "characterId": 17 },
{ "player": "Player 2", "characterId": 20 }
]
}
然后 .aggregate()
方法处理这个要快得多,returns 一个用于大型结果集的游标:
db.collection.aggregate([
{ "$unwind": "$playerInfo" },
{ "$group": {
"_id": "$playerInfo",
"count": { "$sum": 1 }
}}
])
使用 MongoDB 3.4 及更高版本,您甚至可以在现有结构上使用
db.LoL.aggregate([
{ "$project": {
"playerInfo": { "$objectToArray": "$playerInfo" }
}},
{ "$unwind": "$playerInfo" },
{ "$group": {
"_id": {
"player": "$playerInfo.k",
"characterId": "$playerInfo.v.info.characterId"
},
"count": { "$sum": 1 }
}}
])
这与 mapReduce 基本相同,只是由于使用了本机运算符而不是运行速度慢得多的 JavaScript 评估,所以速度要快得多。