2016-07-29 84 views
1

我想這樣做:

model.User.aggregate([ 
    //step 1 match criteria 
    { 
     $match: criteria 
    }, 
    //step 2 skip 
    { 
     $skip: offset 
    }, 
    //step 3 limit 
    { 
     $limit: limit 
    }, 
    //step 4 sort by computed distance 
    { 
     $geoNear : { 
      near: {type: 'Point', coordinates: coords }, 
      distanceField: 'currentCity.computed_distance', 
      includeLocs: 'currentCity.loc', 
      spherical: true, 
      uniqueDocs: true, 
      distanceMultiplier: 3963.2, //convert to miles (this number is the radius of the earth in miles) 
     } 
    } 
],function(err,users){ 
    if (err) return res.error(err); 
    if (!users.length) return res.error('no matched criteria'); 
    res.apiResponse(users); 
}); 

$ geoNear的文檔狀態:

您只能使用$ geoNear作爲管道的第一階段。

閱讀該文檔,我知道我可以在裏面$geoNear通過query選項只需移動$match。同樣,$limit可能通過limit選項放置在$geoNear的內部。一個問題是,$skip選項沒有等效,所以看起來好像無法實現分頁功能?我真的很困惑,爲什麼$geoNear不能成爲第四步。查詢的目的是簡單地找到最好的n匹配,其中n = limit,然後按距離最近排序。這甚至有可能嗎?我無法找到這個特定用例的答案。

我想一個解決方案可能是有$in查詢像這樣執行查詢只選擇IDS匹配的文檔,轉換爲ID的列表,然後做骨料:

model.User.find(criteria).skip(offset).limit(limit).select('_id').exec(function (err, userIds) { 
    var ids = []; 
    userIds.forEach(function(u){ 
     ids.push(u._id); 
    }); 

    model.User.aggregate([ 
     { 
      $geoNear : { 
       query: { _id: {$in: $ids } }, 
       near: {type: 'Point', coordinates: coords }, 
       distanceField: 'currentCity.computed_distance', 
       includeLocs: 'currentCity.loc', 
       spherical: true, 
       uniqueDocs: true, 
       distanceMultiplier: 3963.2, //convert to miles (this number is the radius of the earth in miles) 
      } 
     } 
    ],function(err,users){ 
     if (err) return res.error(err); 
     if (!users.length) return res.error('no matched criteria'); 
     res.apiResponse(users); 
    }); 
}); 

這會工作,但理想情況下,如果可能,我可以在1個查詢中完成。任何想法非常讚賞。

回答

0

一種解決方案是這一個:

result = db.cafes.aggregate([{ 
'$geoNear': { 
    'near': { 
     'type': 'Point', 
     'coordinates': [ 
      -73.991084, 
      40.735863]}, 
    'spherical': True, 
    'distanceField': 'dist', 
    'num': 20} 
}, { 
    '$skip': 10 
}]) 

還有這種方法更好的解決方案:

ids = [42] 

result = db.command(
'geoNear', 'cafes', 
near={ 
    'type': 'Point', 
    'coordinates': [ 
     -73.991084, 
     40.735863]}, 
spherical=True, 
minDistance=268, 
query={ 
    '_id': { 
     '$nin': ids}}, 
num=10) 

而且一個非常好的解釋速度和問題在這裏:

https://emptysqua.re/blog/paging-geo-mongodb/