我的猫鼬查询是:
Spread.find(findCase).where('loc').near({
center: {
type: 'Point',
coordinates: [self.lon, self.lat]
},
maxDistance: distance
}).sort({ts : -1}).distinct("postId").exec();
所以我收到错误:
Error: sort cannot be used with distinct
但是如果我用控制台传递查询
db.spreads.distinct({}).sort({ts: -1});
没关系。
那么为什么 mongoose 不允许我在一个查询中选择不同并排序,我该怎么做?
从 docs 来看,
sort
不能与 distinct
一起使用。
不能与distinct()一起使用
但是你可以执行聚合操作:
Spread.aggregate(
{$geoNear:{
"near":{"type":"Point","coordinates":[self.lon, self.lat]},
"distanceField":"dist.calculated",
"maxDistance":distance,
"query":findcase,
"spherical": true
}},
{$sort:{"ts":-1}},
{$group:{"_id":"$postId"}},function(err,resp){
console.log(resp);
// handle response.
}
)
注意:
2dsphere
索引需要存在于集合中的 loc
字段上。要创建索引,请参阅:在 mongoose 模式上应用 2dsphere 索引是否会强制需要位置字段?。
测试数据:
db.createCollection("test");
db.test.insert({
loc : {type: 'Point', coordinates : [42,42]},
ts : new Date(2014,2,5),
postId : 1
});
db.test.insert({
loc : {type: 'Point', coordinates : [42,42]},
ts : new Date(2014,2,5),
postId : 1
});
db.test.insert({
loc : {type: 'Point', coordinates : [42,42]},
ts : new Date(2014,2,4),
postId : 2
});
db.test.insert({
loc : {type: 'Point', coordinates : [42,42]},
ts : new Date(2014,2,3),
postId : 3
});
有查询
db.test.aggregate([
{
$geoNear: {
near : { type: 'Point', coordinates: [ 42, 42 ] },
distanceField : 'dist.calculated',
maxDistance: 200,
spherical: true
}
},
{
$sort : {ts: -1}
},
{$group:{"_id":"$postId"}}
]);
给出错误的结果
{ "_id" : 3 }
{ "_id" : 2 }
{ "_id" : 1 }
所以我猜mongo首先应用了分组,然后无法按缺失字段排序。因此,猫鼬可能禁止使用不同的排序方式。
mongo.aggregate
的方法,并且需要在应用$sort
之前和之后应用$group
。
因此,例如,如果您想在集合中应用
updated_at
列的 distinct 时保持 name
列的排序标准按降序排列,您应该执行以下操作:
db.collection.aggregate([
{ $sort: { updated_at: -1 } }, // Sort documents by updated_at Descending
{
$group: {
_id: "$name", // Group Documents by name
updated_at: { $first: "$updated_at" } // Capture most recent updated_at
}
},
{ $sort: { updated_at: -1 } }, // Sort groups by updated_at descending (need to be sorted again because the $group removes the sort on its output)
{ $project: { name: "$_id", _id: 0 } } // Project the desired output by filling "name" with the result of "_id" (created from the $group clause) and removes the "_id" afterwards
])
[
{ "name": "Rax Wunter" },
{ "name": "Victorcorcos" },
{ "name": "William James" }
]