2016-07-29 5 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는 파이프 라인의 첫 번째 단계입니다.

설명서를 읽고, 나는 단순히 query 옵션을 통해 $geoNear의 내부 $match를 이동할 수 있습니다 것을 알 수있다. 마찬가지로 $limitlimit 옵션을 사용하여 $geoNear 안에 배치 할 수 있습니다. 한 가지 문제는 $skip 옵션에 해당하는 항목이 없으므로 페이지 매김을 쉽게 수행 할 수없는 것처럼 보입니다. 나는 정말로 여기에서 혼란 스럽다. 왜 $geoNear이 파이프 라인의 4 단계가 될 수 없는지. 검색어의 목표는 n 개의 일치 항목을 찾는 것입니다 (n = limit). 그런 다음 가장 근접한 순서로 정렬합니다. 이게 가능한가? 이 특정 사용 사례에 대한 답을 찾는 데 문제가 있습니다.

나는 하나 개의 솔루션이 그렇게 같은 $in 쿼리로 집계, ID 만 문서를 일치하는 선택 쿼리를 수행 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

하나의 해결책은 이것이다 : 여기에 속도와 문제에

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) 

그리고 정말 좋은 설명 :

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

도이 방법으로 더 나은 솔루션이있다 https://emptysqua.re/blog/paging-geo-mongodb/

관련 문제