猫鼬的排序和区分

问题描述 投票:0回答:3

我的猫鼬查询是:

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 不允许我在一个查询中选择不同并排序,我该怎么做?

node.js mongodb mongoose
3个回答
4
投票

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 索引是否会强制需要位置字段?


0
投票

测试数据:

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首先应用了分组,然后无法按缺失字段排序。因此,猫鼬可能禁止使用不同的排序方式。


0
投票

如果您想在应用distinct时保留之前的顺序,则需要采用

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" }
]
© www.soinside.com 2019 - 2024. All rights reserved.