0

I have the following code running in a perl Mojolicious app. The collection it runs against has a 2d index applied to the "loc" property which is 2 element array of the form [ lat, long ].

MongoDB is 2.0.1, perl MongoDB is 0.46. perl is 64bit

I have no trouble pushing inserting/upserting new documents when the 2d index has been dropped. When the index is applied, last_error returns "location object expected, location array not in correct format"

I've tried manipulating the lat and long input multiple ways, to no avail. Here is the code ... any ideas?

sub checkmein {
    my $self = shift;
    my $mail = $self->stash('mail');
    my $lat  = $self->param('lat');
    my $lng  = $self->param('long');

    # upsert

    my $c = $self->db->checkins;
    $mail = lc $mail;

    my $now = time;
    my @loc = (Math::BigFloat->new($lng),Math::BigFloat->new($lat));

        $c->update(
            {'mail'=>$mail }, 
            { 'mail'=>$mail, 'when'=>$now, 'loc'=>\@loc  }, 
            { upsert=>1 }
        );

    my $err = $self->db->last_error();

    if (defined $err->{'err'}) {
            $self->render(json=>{'status'=>'error','message'=>"Problem checking in $mail to $lat,$lng"});
    } else {
            $self->render(json=>{'status'=>'ok','message'=>"$mail checked in to $lat,$lng"});
    }

}

2
  • The code in your eval can't even compile. Your MongoDB (and MongoDB driver) are also seriously out-of-date, though that's not related to your problem. Commented May 29, 2013 at 14:59
  • yes, planning a mongodb update as we speak. sory about the eval, a bad cut and paste ... should be correct now Commented May 29, 2013 at 15:15

1 Answer 1

1

I'm not an expert on geo indexes, but I think your coordinates may be in the wrong order. According do the documentation for 2d indexes, the array needs to be in the form [ long, lat ], but you have [ lat, long ]. My guess is the indexer is finding a lat/long value to be out of range.

You also can't insert Math::BigFloat values into MongoDB, but if perl thinks they are strings, you can make perl think your values are floats by adding zero to them.

$lat += 0;
$lng += 0;
Sign up to request clarification or add additional context in comments.

2 Comments

yeah, i dont know much about 2d either ... you are correct. I've made that change. now i get this error from MongoDB driver: [error] type (Math::BigFloat) unhandled at /usr/local/lib/perl5/site_perl/5.12.4/x86_64-linux/MongoDB/Collection.pm line 376.
The MongoDB driver does not support BigFloats internally, but there should be no reason to use them for latitude and longitude values. (We do support Math::BigInt if you need to deal with 64-bit ints on a 32-bit perl.) You should be able to just insert them as normal scalars. If they're showing up as strings in the DB, add 0.0 to them to force them to floats. (Updated answer).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.