我正在使用猫鼬和带有maxDistance的near查询来过滤靠近给定gps位置的元素。但是,near查询会覆盖其他排序。我想要的是找到给定点的maxDistance内的所有元素,然后按其他属性排序。这是我目前正在做的一个例子:
模式:
mongoose.Schema({
name: {
type: String,
required: true
},
score: {
type: Number,
required: true,
default: 0
},
location: {
type: {
type: String,
default: 'Point',
},
coordinates: {
type: [Number]
}
},
....
});
查询:
model.find({
"location.coordinates": {
"$near": {
"$maxDistance": 1000,
"$geometry": {
"type": "Point",
"coordinates": [
10,
10
]
}
}
}
}).sort('-score');
在查找后添加.sort在这里无济于事,并且无论如何都会以接近的顺序返回项目。
您是否尝试过使用汇总?我知道常规查询有局限性。
model.aggregate([
{$geoNear: {
near: { type: "Point", coordinates: [ 10 , 10 ] },
distanceField: "distCalculated",
maxDistance: 1000
}},
{$sort:{score:-1}}
])
$near
按距离对文档进行排序,这很浪费。最好使用不对文档进行排序的$geoWithin
。类似于:
model.find({
"location.coordinates": {
$geoWithin: { $center: [ [-74, 40.74], <radius> ] } } }
).sort({score: -1});
$center
文档具有更多详细信息。
正确的语法类似于$ near:
$center
要使$ near工作,您需要在相关集合上使用2dsphere索引:
router.get("/test", async (req, res) => {
const lat = 59.9165591;
const lng = 10.7881978;
const maxDistanceInMeters = 2000;
const result = await model
.find({
location: {
$near: {
$geometry: {
type: "Point",
coordinates: [lng, lat],
},
$maxDistance: maxDistanceInMeters,
},
},
})
.sort("-score");
res.send(result);
});
在mongodb db.collection.createIndex( { "location" : "2dsphere" } )
文档中它说:
$ near按距离对文档进行排序。如果您还包括一个sort()查询sort()有效地对匹配文档进行重新排序覆盖$ near已经执行的排序操作。使用时使用地理空间查询进行sort(),请考虑使用$ geoWithin运算符,不会对文档排序,而不是$ near。
由于您对按距离排序不感兴趣,因为Nic不需要使用$ near,所以最好像这样使用$near:
$geoWithin
为了计算半径,我们按照router.get("/test", async (req, res) => {
const lat = 59.9165591;
const lng = 10.7881978;
const distanceInKilometer = 2;
const radius = distanceInKilometer / 6378.1;
const result = await model
.find({
location: { $geoWithin: { $centerSphere: [[lng, lat], radius] } },
})
.sort("-score");
res.send(result);
});
将公里除以6378.1,将英里除以3963.2。
因此代码将找到半径2公里内的位置。