MongoDB - 使用$ geoNear错误“查询结果太多,截断输出”

时间:2016-10-10 10:26:13

标签: mongodb mongodb-query mongodb-java

我正在分片群集上运行$geoNear查询(6个节点包含3个副本集,每个副本分别为2个shardsvr和1个仲裁器)。 我希望查询返回1.1m文档。我只收到~130.xxx文件。我正在使用Java驱动程序发出查询并处理数据(现在,我只是计算返回的文档)。我正在使用MongoDB 3.2.9和最新的java驱动程序。

mongod日志显示由输出文档大于16MB引起的以下错误:

2016-10-10T12:00:22.933+0200 W COMMAND  [conn22] Too many geoNear results for query { location: { $nearSphere: { type: "Point", coordinates: [ 10.xxxx, 52.xxxxx] }, $maxDistance: 3900.0 } }, truncating output.
2016-10-10T12:00:22.951+0200 I COMMAND  [conn22] command mydb.data command: geoNear { geoNear: "data", near: { type: "Point", coordinates: [ 10.xxxx, 52.xxxxx ] }, 
    num: 50000000, maxDistance: 3900.0, query: {}, spherical: true, distanceMultiplier: 1.0, includeLocs: true } keyUpdates:0 writeConflicts:0 numYields:890 reslen:16777310 
    locks:{ Global: { acquireCount: { r: 1784 } }, Database: { acquireCount: { r: 892 } }, Collection: { acquireCount: { r: 892 } } } protocol:op_query 589ms

2016-10-10T12:00:23.183+0200 I COMMAND  [conn22] getmore mydb.data query: { aggregate: "data", pipeline: [ { $geoNear: { near: { type: "Point", coordinates: [ 10.xxxx, 52.xxxxx ] }, 
    distanceField: "dist.calculated", limit: 50000000, maxDistance: 3900.0, query: {}, spherical: true, distanceMultiplier: 1.0, includeLocs: "dist.location" } }, { $project: { _id: false, 
    dist: { calculated: true } } } ], fromRouter: true, cursor: { batchSize: 0 } } cursorid:170255616227 ntoreturn:0 cursorExhausted:1 keyUpdates:0 writeConflicts:0 numYields:0 nreturned:43558 
    reslen:1568108 locks:{ Global: { acquireCount: { r: 1786 } }, Database: { acquireCount: { r: 893 } }, Collection: { acquireCount: { r: 893 } } } 820ms

查询:

db.data.aggregate([
   {
      $geoNear:{
         near:{
            type:"Point",
            coordinates:[
               10.xxxx,
               52.xxxxx
            ]
         },
         distanceField:"dist.calculated",
         maxDistance:3900,
         num:50000000,
         includeLocs:"dist.location",
         spherical:true
      }
   }
])

请注意,我使用和不使用参数num发出了查询,两者都失败并显示上面显示的错误。

一旦超出文档大小限制(16 MB),我希望查询返回数据库的块。 我错过了什么?如何检索所有数据?

编辑: 当我添加组阶段时,查询也会在mongod日志中出现相同的错误:

db.data.aggregate([
   {
      $geoNear:{
         near:{
            type:"Point",
            coordinates:[
               10.xxxx,
               52.xxxxxx
            ]
         },
         distanceField:"dist.calculated",
         maxDistance:3900,
         includeLocs:"dist.location",
         num:2000000,
         spherical:true
      }
   },
   {
      $group:{
         _id:"$root_document"
      }
   }
])

1 个答案:

答案 0 :(得分:2)

MongoDB工作人员Lungang Fang在此期间回复了我对MongoDB用户组的询问。以下是他的回答:

  

目前,“geoNear”聚合阶段仅限于返回   结果在16MB BSON大小限制范围内。这与。有关   早期版本的MongoDB的问题(在中描述)   https://jira.mongodb.org/browse/SERVER-13486)。您的查询点击此处   因为“geoNear”返回单个文档(包含一个数组)   结果文档)和“allowDiskUse”聚合管道   遗憾的是,在这种情况下,选项无济于事。

     

可以考虑两种选择:

     

如果您不需要所有结果,可以限制“geoNear”   使用num,limit或maxDistance选项聚合结果大小If   你需要所有的结果,你可以使用find()运算符   因为它返回游标,所以不限于BSON最大大小。   以下是我在MongoDB 3.2.10上进行的测试,供您参考。

     

为指定的集合创建“2dsphere”:        function getFlowAmount(fromRegionName, toRegionName) { return _reportPeriodId === 1 ? mapData[toRegionName + 'Region']['NetFlow' + fromRegionName ] : mapData[toRegionName + 'Region']['NetFlowChange' + fromRegionName]; }    创建并插入几个大文档:
  db.coll.createIndex({location: '2dsphere'})

var padding = '';
       for (var j = 0; j < 15; j++) {
           for (var i = 1024*128; i > 0; --i) {
               var padding = padding + '12345678';
           }
       }
     

此致,龙岗