将Aggregate与$ near查询一起使用

时间:2017-08-29 01:51:15

标签: mongodb aggregation-framework

我正在尝试在mongoDB上运行查询并在查询中使用$near。下面的查询有效,但我需要根据LAT和LNG进行聚合。我试图根据与pickup_location保持一定距离的那些来聚合或获取计数。

我在 shell 中使用以下内容,而不是代码。

这是一个记录:

                            {
"_id": {
    "$oid": "5445ab058767000062"
},
"comment": null,
"dropoff_address": "XHgwMmB7fk1lRn59YFx4MDM=U2FsdGVkX19s3u4NEtImfofJzxnGreGpsna8qA4uVrq7exRDVy+zPn5UwDOj\nzpIs",
"dropoff_location": [
    -97.816991,
    30.189151
],
"pickup_address": "XHgwMmB7fk1lRn59YFx4MDM=U2FsdGVkX1/23mD3Vv3Nyf4/t+AEickIgOlkaxVp5y/e/5Ia2d3Z0OXtnejw\nrOK+ZPvxQontA9SS30t+MbUIrCMhndxpYcKNFm4xfOzRVxM=",
"pickup_location": [
    -97.82075191025548,
    30.20993147664687
],
"scheduled_request": false,
"status": "blah",
"timestamp_requested": {
    "$date": "2014-10-21T00:38:28.990Z"
},
"total_owed_in_cents": 0,
"total_received_from_in_cents": 0,
"user_id": "5445a9000057"

}

这项工作:

db.thing_requests.aggregate(
       [
         {$match: {total_received_in_cents: {$gt:1800}, requested_type: 'Blah' }},
         {
           $group:
             {
               _id: null,
               average: { $avg: "$total_received_in_cents" }
             }
         }
       ]
    )

需要增加上面的工作:

{
     the_location: {
       $near: {
         $geometry: {
            type: "Point" ,
            coordinates: [ <longitude> , <latitude> ]
         },
         $maxDistance: <distance in meters>,
         $minDistance: <distance in meters>
       }
     }
  }

更新:

顶级查询有效。我需要的是说所有聚集的项目我还需要确保它们接近某个LAT&amp; LNG。

更新2:

跑过这个问题

      db.thing_requests.aggregate([
           {
             $geoNear: {
                near: { type: "Point", coordinates: [ -97.888,37.3222 ] },
                distanceField: "dist.calculated",
                maxDistance: 2,
                minDistance :1,
                query: {total_received_in_cents: {$gt:1800}, requested_type: 'Blah' },
                includeLocs: "dist.location",
                num: 5,
                spherical: true
             }
           },
         {
           $group:
                 {
                   _id: "$user_id",
                   average: { $avg: "$total_received_from_requester_in_cents" }
                 }

         }
        ])

收到此错误:

assert: command failed: {
      "errmsg" : "exception: geoNear command failed: { ok: 0.0, errmsg: \"no geo indices for geoNear\" }",
      "code" : 16604,
      "ok" : 0
    } : aggregate failed
    Error: command failed: {
      "errmsg" : "exception: geoNear command failed: { ok: 0.0, errmsg: \"no geo indices for geoNear\" }",
      "code" : 16604,
      "ok" : 0
    } : aggregate failed
        at Error (<anonymous>)
        at doassert (src/mongo/shell/assert.js:11:14)
        at Function.assert.commandWorked (src/mongo/shell/assert.js:254:5)
        at DBCollection.aggregate (src/mongo/shell/collection.js:1278:12)
        at (shell):1:23
    2017-08-28T21:21:40.153-0500 E QUERY    Error: command failed: {
      "errmsg" : "exception: geoNear command failed: { ok: 0.0, errmsg: \"no geo indices for geoNear\" }",
      "code" : 16604,
      "ok" : 0
    } : aggregate failed
        at Error (<anonymous>)
        at doassert (src/mongo/shell/assert.js:11:14)
        at Function.assert.commandWorked (src/mongo/shell/assert.js:254:5)
        at DBCollection.aggregate (src/mongo/shell/collection.js:1278:12)
        at (shell):1:23 at src/mongo/shell/assert.js:13

1 个答案:

答案 0 :(得分:1)

在第一阶段使用$ geoNear

db.thing_requests.aggregate([
   {
     $geoNear: {
        near: { type: "Point", coordinates: [ long,lat ] },
        distanceField: "dist.calculated",
        maxDistance: 2,
        minDistance :1,
        query: {total_received_in_cents: {$gt:1800}, requested_type: 'Blah' },
        includeLocs: "dist.location",
        num: 5,
        spherical: true
     }
   },
 {
   //use $group here
 }
])

你也可以使用$ near

db.thing_requests.find( {
   the_location: {
 $near: {
   $geometry: {
      type: "Point" ,
      coordinates: [ <longitude> , <latitude> ]
   },
   $maxDistance: <distance in meters>,
   $minDistance: <distance in meters>
 }
 },total_received_in_cents: {$gt:1800}, requested_type: 'Blah'
 });

但无论如何你需要在&#34; the_location&#34;上指定一个地理空间(2d,2dsphere)索引。领域 如果您使用猫鼬,有一种简单的方法可以做到这一点 在架构中指定2d或2dsphere索引

    the_location: {
    type: [Number],   // format will be [ <longitude> , <latitude> ]
    index: '2dsphere'       // create the geospatial index
}

或使用db命令

db.collection.createIndex( { <location field> : "2dsphere" } )

更为有利https://docs.mongodb.com/manual/geospatial-queries/