简体   繁体   中英

Node.js, MongoDB - Mongoose - calculate average as part of GEO search

I am using Mongoose to execute a geo polygon search as follows:

    Location.find({
    "location.coordinates": {
        "$geoWithin": {
            "$geometry": {
                "type": "Polygon",
                "coordinates": [
                    coords
                ]
            }
        }
    }
}, cb);

This returns a set of records such as:

      {
    "_id": "544be0763cea87660ee9c989",
    "rating": 5,
    "__v": 0,
    "create_date": "2014-10-25T17:40:06.167Z",
    "location": {
      "coordinates": [
        -122.41941550000001,
        37.7749295
      ],
      "type": [
        "Point"
      ]
    }
  },
  {
    "_id": "544be0763cea87660ee9c989",
    "rating": 7,
    "__v": 0,
    "create_date": "2014-09-27T01:40:10.283Z",
    "location": {
      "coordinates": [
        -122.41941550000001,
        37.7749295
      ],
      "type": [
        "Point"
      ]
    }
  }

I need to also calculate an average of the "rating" property. I know Mongo has an aggregation framework but im not sure if this can be done as part of the initial search, or as a secondary query, or look to post process the results.

Can anyone advise?


UPDATE: To be clear, I would like to return the current result set, AND the average rating for the entire result set if possible.

You are clearly using MongoDB 2.6 or greater on the server by the query syntax you are using. This basically forms your answer as it was in this version the at the query engine was unified so that GeoSpatial queries are run in the same space as other queries.

This means that exactly the same query is available to the aggregation framework as well, since this uses regular queries itself:

    Location.aggregate(
        [
            // Perform query
            { "$match": {
                "location.coordinates": {
                    "$geoWithin": {
                        "$geometry": {
                            "type": "Polygon",
                            "coordinates": [
                                coords
                             ] 
                         }
                     }
                 }
             }},

            // Get average from results
            { "$group": {
                "_id": null,
                "avgRating": { "$avg": "$rating" }
            }}
        ],
        function(err,results) {

        }
    );

Most GeoSpatial queries would need to be the first pipeline stage, there is in fact a special stage to project distance with $geoNear . But I think $geoWithin is fine at later pipeline stages, but is of course most optimal where it can use an index. That means in the first stage only.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM