我正在计算每个邮政编码中有多少条记录。
在我的MongoDB中,邮政编码是嵌入的;使用点表示法,它位于a.res.z (a表示地址,res表示住宅,z表示zip)。例如:
db.NY.count({'a.res.z' : '14120'})
但是当我尝试map函数时(在python中,因为我使用PyMongo):
map = Code("function () {"
" emit(this.a.res.z, 1);"
"}")
当我调用mapreduce:
时,我得到这个错误pymongo.errors.OperationFailure: db assertion failure, assertion: 'map invoke failed: JS Error: TypeError: this.a has no properties nofile_b:0', assertionCode: 9014
点表示法在顶层工作-例如一个点-但我不能让它在嵌入上工作。秘诀是什么?
此错误意味着至少有一个您正在映射减少的对象缺少其a
的res
字段。看到:
> db.NY.find({}, {_id: 0})
{ "a" : { "res" : { "z" : 10011 } }, "name" : "alice" }
{ "a" : { "res" : { "z" : 10011 } }, "name" : "bob" }
{ "a" : { "res" : { "z" : 10012 } }, "name" : "carol" }
> m
function () {
emit(this.a.res.z, 1);
}
> r
function (key, values) {
var v = 0;
values.forEach(function (obj) {v += obj;});
return v;
}
> db.runCommand({mapreduce: "NY", map: m, reduce: r, out: {inline: 1}})
{
"results" : [
{
"_id" : 10011,
"value" : 2
},
{
"_id" : 10012,
"value" : 1
}
],
"timeMillis" : 0,
"counts" : {
"input" : 3,
"emit" : 3,
"output" : 2
},
"ok" : 1
}
> db.NY.insert({a: {}, name: "empty"})
> db.runCommand({mapreduce: "NY", map: m, reduce: r, out: {inline: 1}})
{
"assertion" : "map invoke failed: JS Error: TypeError: this.a.res has no properties nofile_b:1",
"assertionCode" : 9014,
"errmsg" : "db assertion failure",
"ok" : 0
}
你可以使用query
参数来映射-reduce,只对那些你想要的字段进行操作:
> db.runCommand({mapreduce: "NY", map: m, reduce: r, out: {inline: 1},
query: {"a.res.z": {$exists: true}}})
{
"results" : [
{
"_id" : 10011,
"value" : 2
},
{
"_id" : 10012,
"value" : 1
}
],
"timeMillis" : 1,
"counts" : {
"input" : 3,
"emit" : 3,
"output" : 2
},
"ok" : 1
}
要使用PyMongo中的query
参数,您可以将其设置为关键字参数map_reduce(...)