Search code examples
mongodbgeolocationmeteorlatitude-longitude

How to return documents closest to a geographical location?


I would like to display posts nearest to a user entered geolocation in meteor.

User adds the post on addpost template:

     //events.js (this code works nicely)

Template.addpost.events ({
    'click .add': function (evt, tmpl) {
         var title = tmpl.find('.title').value;
         var lat = tmpl.find('.address-lat').value;
         var long = tmpl.find('.address-long').value;
         var loc = lat , long
         Post.insert({title:title,loc:loc});

})

Then it was displayed on the main page using this code:

    //main.js (this works)

Post = new Meteor.Collection("posts");

Template.main.posts = function() {
    return Post.find();
}

and html:

(this works)

{{#each posts}}
    <tr>
        <td>{{title}}</td>
    </tr>
{{/each}}


Now my question is: how can i filter these posts, and display the nearest 100 for user specified latitudes and longitudes?

(the mondodb code for this can be found here: http://docs.mongodb.org/manual/reference/operator/query/near/)


Solution

  • The documentation suggests that $near sorts the results from nearest to farthest. Hence, you can do the following on the server (while publishing) or the client (if you have all the records already):

    Template.main.posts = function () {
        var totalRecords = Post.find().count();
        return Post.find({
                loc : {
                    $near : {
                        $geometry : { 
                            type : "Point",
                            coordinates: [ userLocLong, userLocLat ] 
                        } 
                    } 
                } 
            }, { 
                limit: 100  // Return only the nearest 100 results
            }
        );
    };
    

    Note from OP:

    The code actually works. Just found out that you need to add coordinates in this format to posts collection:

    Post.insert({
    
            loc: {
                      type: "Point",
                      coordinates: [foo, bar],
                 }
        });