How to group longitude and latitude reducing the decimal places of those points?

时间:2017-08-30 20:10:30

标签: mongodb mongodb-query aggregation-framework

I have the following aggregate:

getlist

And the following collection:

   Event.getList().then(function(data){
        $scope.events = data.events;
        $rootScope.events = data.events;
    });

When I run the aggregate, I have the following result:

href = "{{ some_object.file_name.url }}" 

I would like to group these locations in a single document, since they are very close ..

I thought of reducing the size of each point, db.locations.aggregate( // Pipeline [ // Stage 1 { $geoNear: { near: { type: "Point", coordinates: [-47.121314, -18.151515 ] }, distanceField: "dist.calculated", maxDistance: 500, includeLocs: "dist.location", num: 50000, spherical: true } }, // Stage 2 { $group: { "_id" : { 'loc' : '$loc' }, qtd: { $sum:1 } } }, ], ); being something like { "_id" : ObjectId(), "loc" : { "type" : "Point", "coordinates" : [ -47.121311, -18.151512 ] } }, { "_id" : ObjectId(), "loc" : { "type" : "Point", "coordinates" : [ -47.121311, -18.151512 ] } }, { "_id" : ObjectId(), "loc" : { "type" : "Point", "coordinates" : [ -47.121312, -18.151523 ] } }, { "_id" : ObjectId(), "loc" : { "type" : "Point", "coordinates" : [ -47.121322, -18.151533 ] } }

Something like this

{ 
    "_id" : {
        "loc" : {
            "type" : "Point", 
            "coordinates" : [
                -47.121311, 
                -18.151512
            ]
        }
    }, 
    "qtd" : 2.0
},
{ 
    "_id" : {
        "loc" : {
            "type" : "Point", 
            "coordinates" : [
                -47.121312, 
                -18.151523
            ]
        }
    }, 
    "qtd" : 1.0
},
{ 
    "_id" : {
        "loc" : {
            "type" : "Point", 
            "coordinates" : [
                -47.121322, 
                -18.151533
            ]
        }
    }, 
    "qtd" : 1.0
}

But I have no idea how to group these documents.

Is it possible?

1 个答案:

答案 0 :(得分:1)

降低浮点精度的方法是通过所需的精度调整将$multiply输出数字,"截断它"到一个整数然后$divide回到所需的精度。

对于最新的MongoDB版本(自MongoDB 3.2起),您可以使用$trunc

db.locations.aggregate([
  { "$geoNear": {
    "near": { 
      "type": "Point", 
      "coordinates": [ -47.121314, -18.151515 ]
    },
    "distanceField": "qtd",
    "maxDistance": 500,
    "num": 50000,
    "spherical": true
  }},
  { "$group": {
    "_id": {
      "type": '$loc.type',
      "coordinates": {
        "$map": {
          "input": '$loc.coordinates',
          "in": {
            "$divide": [
              { "$trunc": { "$multiply": [ '$$this', 10000 ] } },
              10000
            ]                
          }
        }    
      }
    },
    "qtd": { "$sum": '$qtd' }    
  }}
]);

对于之前的版本,您可以使用$mod$subtract删除"余数"代替:

db.locations.aggregate([
  { "$geoNear": {
    "near": { 
      "type": "Point", 
      "coordinates": [ -47.121314, -18.151515 ]
    },
    "distanceField": "qtd",
    "maxDistance": 500,
    "num": 50000,
    "spherical": true
  }},
  { "$group": {
    "_id": {
      "type": '$loc.type',
      "coordinates": {
        "$map": {
          "input": '$loc.coordinates',
          "as": "coord",
          "in": {
            "$divide": [
              { "$subtract": [
                { "$multiply": [ '$$coord', 10000 ] },
                { "$mod": [
                  { "$multiply": [ '$$coord', 10000 ] },
                  1
                ]}
              ]},
              10000
            ]                
          }
        }    
      }
    },
    "qtd": { "$sum": '$qtd' }    
  }}
]);

两者都返回相同的结果:

/* 1 */
{
    "_id" : {
        "type" : "Point",
        "coordinates" : [ 
            -47.1213, 
            -18.1515
        ]
    },
    "qtd" : 4.01180839007879
}

我们在这里使用$map"重塑" "coordinates"的数组内容应用"舍入"到数组中的每个值。您可能会注意到第二个示例中使用"as'的两个略有不同的用法,因为使用$$this作为默认引用的功能仅适用于MongoDB 3.2,其中列表假设您没有或否则你将使用$trunc而不是替代方法用法。

你应该注意$geoNear本质上是一个"最近的"搜索默认只返回100个文档,或者最多返回"num""limit"选项中指定的数字。因此,如果这些结果超出"maxDistance"等其他约束条件,那么它始终是返回结果数量的一个控制因素。

也没有必要按字面意思来遵循文档,因为"distanceField"是除"spherical"之外的唯一其他强制参数,在使用"2dsphere"索引时是必需的。 "distanceField"的值可以是您实际想要的值,在这种情况下,我们只是直接提供您想要输出的属性的名称。