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

What every Java engineer should know about microservices: Reactive Microservices Architecture.  Brought to you in partnership with Lightbend.

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.




Microservices for Java, explained. Revitalize your legacy systems (and your career) with Reactive Microservices Architecture, a free O'Reilly book. Brought to you in partnership with Lightbend.

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 }}