Geospatial $near within current document field value

北城余情 提交于 2019-11-26 10:03:43

问题


Take this query:

{ \'location\' : { \'$near\' : [x,y], \'$maxDistance\' : this.field } }

I want to assign $maxDistance the value of the specified field from the current evaluated document. Is that possible?


回答1:


Yes it's possible. You just use $geoNear instead. Beware the catches and read carefully.

Presuming that your intent to is to store a field such as "travelDistance" to indicate on the document that any such searches must be "within" that supplied distance from the queried point to be valid. Then we simply query and evaluate the condition with $redact:

db.collection.aggregate([
  { "$geoNear": {
    "near": { 
      "type": "Point",
      "coordinates": [x,y]
    },
    "spherical": true,
    "distanceField": "distance"
  }},
  { "$redact": {
    "$cond": {
      "if": { "$lte": [ "$distance", "$travelDistance" ] },
      "then": "$$KEEP",
      "else": "$$PRUNE"
    }
  }}
])

The only catch is that $geoNear just like $near will only return a certain number of documents "near" in the first place. You can tune that with the options, but unlike the general query form, this is basically guaranteeing that the eventual returned results will be less than the specified "nearest" numbers.

As long as you are aware of that, then this is perfectly valid.

It is in fact the general way to deal with qualifying what is "near" within a radius.

Also be aware of the "distance" according to how you have the coordinates stored. As legacy coordinate pairs the distances will be in radians which you will probably need to do the math to convert to kilometers or miles.

If using GeoJSON, then the distances are always considered in meters, as the standard format.

All the math notes are in the documentation.

N.B Read the $geoNear documentation carefully. Options like "spherical" are required for "2dsphere" indexes, such as you should have for real world coordinates. Also "limit" may need to be applied to increase past the default 100 document result, for further trimming.


As the comments mention spring mongo, then here is basically the same thing done for that:

Aggregation aggregation = newAggregation(
    new AggregationOperation() {
      @Override
      public DBObject toDBObject(AggregationOperationContext context) {
        return new BasicDBObject("$geoNear",
          new BasicDBObject(
            "near", new BasicDBObject(
              "type","Point")
              .append("coordinates", Arrays.asList(20,30))
            )
            .append("spherical",true)
            .append("distanceField","distance")
          );
        }
    },
    new AggregationOperation() {
      @Override
      public DBObject toDBObject(AggregationOperationContext context) {
        return new BasicDBObject("$redact",
          new BasicDBObject(
            "$cond", Arrays.asList(
               new BasicDBObject("$lte", Arrays.asList("$distance", "$travelDistance")),
               "$$KEEP",
               "$$PRUNE"
             )
          )
       );
     }
    }
);


来源:https://stackoverflow.com/questions/44694847/geospatial-near-within-current-document-field-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!