2012-12-20 118 views
1

我有一個問題已經花了我幾天,我完全不明白它。我使用node.js,並有一個mongodb,它們的座標爲索引。我證實,索引工作正常。對於一組座標,我想找到最近的地方。以下是我試圖去了解它:RangeError當試圖用貓鼬/ mongodb本地執行mongodb查詢

var Places = require(./models/places.js), 
     coordFinder = require('./coordFinder.js'); 

    ... 

    function getCoords(userId, callback) { 
     coordFinder.getCoords(userId, function(err, coords) { 
      if (err) { 
      callback(err); 
      } else { 
      callback(null, coords); 
      } 
     } 
    } 

    function getNearestPlaces(coords, callback) { 
     async.forEachSeries(
      coords, 
      function(coord, done) { 
      Places.findOne(
       { coordinates: { $near: [ coord.lat, coord.lon ] } }, 
       function(err, place) { 
        // do something with place 
        done(); 
       } 
      ) 
      }, 
      function(err) { 
      callback(err ? err : null);  
      } 
     ); 
    } 

    ... 

    async.waterfall(
     [ 
      ... 
      getCoords, 
      getNearestPlaces, 
      ... 
     ], 
     function(err) { 
      ... 
     } 
    } 

MongoDB的查詢始終失敗,第一個查詢以下錯誤信息:

RangeError: Maximum call stack size exceeded 

當我改變getNearestPlaces查詢到

... { $near: [ 10, 10 ] } ... 

我始終沒有錯誤和正確的地方。如果我避免調用coordFindergetCoords和改變getCoords

function getCoords(userId, callback) { 
    callback(
     null, 
     [ 
      // some coordinates 
     ] 
    ); 

我知道錯誤指示堆棧溢出(增加堆棧的大小並沒有幫助),但我無法弄清楚如何我同樣的情況,可能導致了一個。有沒有人知道爲什麼發生這種情況?提前感謝您的見解!

編輯:它使用時mongodb-native直接的方式,所以mongoose似乎不是問題得到了同樣的問題。還有一個線索 - 使用相同的查詢從不給我一個問題,當我不從回調中調用它。這可能是錯誤的根源嗎?

我使用

  • 的node.js 0.6.14
  • mongodb的2.2.2
  • 節點模塊異步0.1.22
  • 節點模塊的mongodb 1.2.5
  • 節點模塊貓鼬2.5 .7

乾杯, Georg

+0

你使用地理空間索引嗎? –

+0

是的,我願意。過去工作得很好,並且在執行mongo shell的查詢時工作正常。 – BumbleGee

+0

這個失敗時,coords數組中有多少個元素? – JohnnyHK

回答

1

mjhm指出我在正確的方向。顯然,傳遞給mongoose查詢的Number實例導致堆棧溢出。我不知道爲什麼,但是從舊的Number對象(如mjhm建議的)創建一個新的Number對象,或者將該數字轉換爲帶有valueOf()的基元解決了這個問題。

如果有人知道原始數字對象如何導致堆棧溢出,我非常感謝您可能需要提供的任何見解。

2

問題很可能來自async.forEachSeries的隱藏遞歸。試着用setTimeout這樣包裹Places.findOne電話:

function getNearestPlaces(coords, callback) { 
    async.forEachSeries(
     coords, 
     function(coord, done) { 
     setTimeout(function() { 
      Places.findOne(
       { coordinates: { $near: [ coord.lat, coord.lon ] } }, 
       function(err, place) { 
        // do something with place 
        done(); 
       } 
      ); 
     }, 1); 
     }, 
     function(err) { 
     callback(err ? err : null);  
     } 
    ); 
} 

這使Places.findOne通話async.forEachSeries調用堆棧之外。

+0

試過但得到了同樣的錯誤。有趣。 – BumbleGee