Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Debugging “object has no properties” in a MongoDB map/reduce

DZone's Guide to

Debugging “object has no properties” in a MongoDB map/reduce

· Java Zone
Free Resource

Managing a MongoDB deployment? Take a load off and live migrate to MongoDB Atlas, the official automated service, with little to no downtime.

You got to love debugging JavaScript errors. Here’s one from a MongoDB map/reduce. The operation fails with this:

    04:39:41  Database command 'mapreduce' failed: (
        assertion: 'map invoke failed: JS Error:
            TypeError: spline has no properties nofile_b:7';
        assertionCode: '9014';
        errmsg: 'db assertion failure';
        ok: '0.0').

Examining the MongoDB log we notice that the map/reduce completes to about 70%, so this is caused by some data inside the database. In this case the issue is in the spline object being accessed by the map function. Indeed, the map tries to fetch spline.reticulated, which is hopefully a Boolean value. The error “spline has no properties” is, generally, another way of saying “spline is null”. In my case splines live in an embedded collection inside bones, and aren’t expected to be null, so I need to track down a null spline inside bone.splines.

While we can just look for a null embedded object, more generally, we can find whether a JS object has no properties with this isEmpty function from SO. Declare it in the mongodb console (use a 1-liner):

    function isEmpty(map) {
        for(var key in map) {
            if (map.hasOwnProperty(key)) {
                return false;
            }
        }
        return true;
    }

Iterate over all bones records.

    db.bones.find().forEach(function(bone) {
        if (bone.splines) {
            bone.splines.forEach(function(spline) {
                if (isEmpty(spline)) {
                    printjson(bone);
                }
            }
        );
    }});

Here’s the culprit, notice the null embedded spline.

{
    "_id" : ObjectId("507ea06bd646a40002000759"),
    "splines" : [
        {
            "_id" : ObjectId("508a6911c6e210000200078c"),
                        ....
        },
        null
    ],

You can get rid of it in different ways on the mongo console. In this case we have two splines, one to keep and another to erase.

    var bone = db.bones.findOne({ _id: ObjectId("507ea06bd646a40002000759") })
    bone.splines = [ bone.splines[0] ];
    db.bones.save(a);

How did we get into having this null record anyway? See https://jira.mongodb.org/browse/SERVER-831 and https://github.com/mongoid/mongoid/issues/2545.




MongoDB Atlas is the easiest way to run the fastest-growing database for modern applications — no installation, setup, or configuration required. Easily live migrate an existing workload or start with 512MB of storage for free.

Topics:

Published at DZone with permission of Daniel Doubrovkine. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}