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.