简体   繁体   中英

Mongo: How to query documents in another collection close to specific location?

I have 2 collections:

var shopSchema = new Schema({
    name: String,
    location: {type: [Number], index: '2dsphere'}, //lng, lat
})

var favoriteShopSchema = new Schema({
    shop: {type: Schema.Types.ObjectId, ref: 'Shop'},
    isActive: {type: Boolean, default: true},
    created: {type: Date, default: new Date()}
})

I need to get favorite shops close to a specific location.

If it will be for shops but not favorite shops, I would simply do that:

Shop.find({ 
    location:
            { $near:
                {
                    $geometry: {type: "Point", coordinates: [location[0], location[1]]}, //location: [lng,lat]
                    $maxDistance: 20 * 1000
                }
}

But how to do for favorite shops?

To complicate the situation, I would like to limit my results and manage by pages.

To summarize what I tried:

1.

let perPage = 10;
let page = req.body.page || 1;

let offers = await FavoriteShop.find({
            "shop.location":
                { $near:
                        {
                            $geometry: {type: "Point", coordinates: [req.body.lng, req.body.lat]}, //location: [lng,lat]
                            $maxDistance: 5 * 1000
                        }
                }
        })
            .populate('shop', 'name location')
            .skip((perPage * page) - perPage)
            .limit(perPage)
            .exec(async function(err, results) {
                if(err || !results) {
                    return res.status(404).end();
                }
                return res.send({
                    offers: results,
                    current: page,
                    pages: Math.ceil(results.length / perPage)
                })
            });

--> No results which is normal I guess because populate() is fetched after find().

2.

offers = await FavoriteShop.aggregate([
    { "$geoNear": {
            "near": {
                "type": "Point",
                "coordinates": {type: "Point", coordinates: [req.body.lng, req.body.lat]}
            },
            "spherical": true,
            "limit": 150,
            "distanceField": "distance",
            "maxDistance": 10 * 1000
        }},
    { "$lookup": {
            "from": "shops",
            "localField": "shop",
            "foreignField": "location",
            "as": "offer"
        }}
]);

--> "MongoError: geoNear command failed: { ok: 0.0, errmsg: "no geo indices for geoNear" }"

Thank you in advance for your help.

I solved the issue like that:

Shop.aggregate([
        {
            $geoNear: {
                near: {
                    type: "Point",
                    coordinates:  [req.body.lng, req.body.lat]
                },
                distanceField: "distance",
                includeLocs: "location",
                spherical: true,
                maxDistance: 1 * 1000
            }},
        { $lookup: {
                from: "favoriteshops",
                localField: "_id",
                foreignField: "shop",
                as: "offers"
            }
        },
        { $unwind: '$offers' }
    ]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM