MongoDB/PyMongo:如何在Map函数中使用点符号? [英] MongoDB/PyMongo: How to use dot notation in a Map function?

查看:134
本文介绍了MongoDB/PyMongo:如何在Map函数中使用点符号?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试计算每个邮政编码中有多少条记录.
在我的MongoDB中,嵌入了邮政编码.使用点表示法,它位于a.res.z(地址为a,住宅为res,邮编为z).例如,这很好用:

I'm trying to count how many records I have located in each zip code.
In my MongoDB, zip code is embedded; using dot notation, it's located at a.res.z (a for address, res for residential, z for zip). For example, this works just fine:

db.NY.count({'a.res.z' : '14120'})

但是当我尝试使用map函数(在python中,因为我使用的是PyMongo)时:

But when I try the map function (in python, because I'm using PyMongo):

map = Code("function () {"
           "    emit(this.a.res.z, 1);"
           "}")

调用mapreduce时出现此错误:

I get this error when I call mapreduce:

pymongo.errors.OperationFailure: db assertion failure, assertion: 'map invoke failed: JS Error: TypeError: this.a has no properties nofile_b:0', assertionCode: 9014

点表示法在顶层起作用-例如一个点-但我无法在嵌入式系统上使用它.有什么秘诀?

Dot notation works at the top level - e.g. one dot - but I can't get it to work on embeddeds. What's the secret?

推荐答案

此错误表示您要进行地图缩小的至少一个对象缺少其ares字段.参见:

This error means that at least one object you're map-reducing is missing the res field of its a. See:

> 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自变量来map-reduce仅对具有所需字段的对象进行操作:

You can use a query argument to map-reduce to operate only on those that have the fields that you want:

> 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(...)

To use the query argument from PyMongo, you can set it as a keyword argument to map_reduce(...)

这篇关于MongoDB/PyMongo:如何在Map函数中使用点符号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆