我有一个商店列表,它们有一个 useCount 和一个地理位置。 我将如何通过 useCount 进行搜索和排序,同时在返回的每个对象上都有一个属性,表示它们离我有多近。
架构:
{
name: String,
useCount: { type: Number, index: true },
location: { 'type': {type: String, enum: "Point", default: "Point"}, coordinates: { type: [Number], default: [0,0]} }
}
例如结果
shop1 usecount-12 closest-3 geo-1333.222,222.222
shop2 usecount-3 closest-1 geo-1333.222,222.222
shop3 usecount-1 closest-2 geo-1333.222,222.222
最佳答案
假设您的数据实际上是为 MongoDB 正确安排的并且看起来像这样:
{
"shop": 1,
"usecount": 12,
"closest": 3,
"geo": {
"type": "Point",
"coordinates": [1333.222,222.222]
}
}
并且您的坐标实际上按照 GeoJSON 和 MongoDB 的要求按“经度/纬度”顺序排列,并且您的地理空间索引为 "2dsphere" ,那么“复合排序”的最佳选择是使用 $geoNear
聚合命令管道,以及聚合 $sort
:
Model.aggregate(
[
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [1333.222,222.222]
},
"distanceField": "dist",
"spherical": true
}},
{ "$sort": { "dist": 1, "usecount": -1 } }
],
function(err,results) {
}
)
$geoNear
将“distance”转换为“dist”中的指定字段,然后在 $sort
中将其与其他字段一起使用此处显示的“usecount”按“最大”值的降序排列,如果“usecount”在前,并且在每个“dist”内已经排序。
.aggregate()
的聚合框架不仅仅是“聚合”文档。它是将新值转换到文档中的“主要工具”,可用于按通过一种或另一种方式“计算”的值对结果进行排序等操作。
不同于$near
(或 $nearSphere
)距离作为文档中的真实字段返回,而不仅仅是“默认”排序顺序。这允许在排序结果中使用该键,以及在 $sort
阶段出现或转换到文档中的任何其他字段值。
另请注意,您在此处的数据似乎不是有效的球坐标,这将导致 GeoJSON 存储和“2dsphere”索引出现问题。如果不是真正的全局坐标而是“平面”上的坐标,则只需将“geo”的平面遗留数组用作 [1333.222,222.222]
和仅“2d”索引。以及“的参数$geoNear
中的 near"也只是一个数组,因此不需要“球形”选项。
但输入您的问题也可能有问题。
关于mongodb - Mongo 用另一个次级排序订购 $near,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32397786/