Home > Mobile >  MongoDB: How do I find coordinates nearby?
MongoDB: How do I find coordinates nearby?

Time:01-24

In this function, I want to check if there are any posts in the database made nearby to a set of input lat/long coords so that I can display them based on where the user currently is, and I also want to write a function to check if they are in a "too close" range (less than 2m or so).

I'm not sure how to do it properly and every answer I have found online after extensive research has given me nothing. I am using NodeJS 18 LTS with the latest version of mongodb.

This is the code I tried to get the posts

const getPostsInRange = (lng, lat) => {

    // get all posts in range
    const postCollection = db.collection('posts')

    return postCollection.find({
        "location": {
            "$near": [parseFloat(lng), parseFloat(lat)],
            "$maxDistance": 100000
        }})


}

and here is the code that calls it, from index.js

app.get('/getposts/:lat/:long', requiresAuth(), (req, res) => {

    const { lat, long } = req.params

    getPostsInRange(long, lat)
        .then((posts) => {

            res.send(posts)

        })
        .catch((err) => {
            console.log(err)
            res.status(500).end()
        })

what my data looks like in mongodb:

{
        "textBody": "new message 3",
        "image": "xxxx",
        "location": {
            "type": "Point",
            "coordinates": [xxxx, xxxx]
        },
        "timestamp": 1674503437
}

I get errors such as TypeError: getPostsInRange(...).then is not a function, and similar but slightly different ones that Google seems to have never have heard of.

i would love some help building this project, full code snippets would be greatly appreciate due to my lack of experience working with mongodb.

CodePudding user response:

It looks like the issue is with the getPostsInRange function not returning a Promise, which is necessary for the .then and .catch to work. The find method from the MongoDB Node.js driver returns a Cursor, which is not a Promise but does have a toArray method that can be used to convert the results to an array and return a Promise.

Here is an example of how you can modify the getPostsInRange function to return a Promise:

const getPostsInRange = (lng, lat) => {

    // get all posts in range
    const postCollection = db.collection('posts')

    return postCollection.find({
        "location": {
            "$near": [parseFloat(lng), parseFloat(lat)],
            "$maxDistance": 100000
        }
    }).toArray();
}

This will make the getPostsInRange function return a Promise that resolves with an array of posts.

It is also worth mentioning that the $near operator requires MongoDB to have a 2dsphere index on the location field, which you can create by running the following command in your MongoDB shell:

db.posts.createIndex({ location: "2dsphere" })

Also you need to make sure that your location object in the document is in the correct format like {type:"Point",coordinates:[long,lat]}.

Hope this helps!

  • Related