sql >> Database >  >> NoSQL >> MongoDB

MongoDb near/geonear query met variabele afstand

U kunt dit niet doen met een normale query omdat u de afstand per document niet dynamisch kunt instellen. Vanaf MongoDB 2.4 kun je dit doen met het aggregatieraamwerk, omdat ze de geoNear-operator hebben toegevoegd aan de start van pijpleidingen.

De eerste fase is de geoNear, die erg lijkt op de opdracht geonear. We krijgen als resultaat ook de afstand van het gespecificeerde punt (10,10) tot het document.

In de tweede fase moeten we de projectoperator gebruiken om het verschil tussen het veld maximumDistance en de berekende geoNear-afstand toe te voegen.

Ten slotte matchen we die documenten die een positieve delta hebben ((max - afstand)> 0).

Hier is de pijplijn met behulp van de Asynchronous Java Driver 's hulpklassen.

package example;

import static com.allanbank.mongodb.builder.AggregationProjectFields.include;
import static com.allanbank.mongodb.builder.QueryBuilder.where;
import static com.allanbank.mongodb.builder.expression.Expressions.field;
import static com.allanbank.mongodb.builder.expression.Expressions.set;
import static com.allanbank.mongodb.builder.expression.Expressions.subtract;

import com.allanbank.mongodb.bson.element.ArrayElement;
import com.allanbank.mongodb.builder.Aggregate;
import com.allanbank.mongodb.builder.AggregationGeoNear;
import com.allanbank.mongodb.builder.GeoJson;

public class AggregateGeoNear {
    public static void main(String[] args) {
        Aggregate aggregate = Aggregate
                .builder()
                .geoNear(
                        AggregationGeoNear.builder()
                                .location(GeoJson.p(10, 10))
                                .distanceField("distance"))
                .project(
                        include("name", "location", "maximumDistance"),
                        set("delta",
                                subtract(field("maximumDistance"),
                                        field("distance"))))
                .match(where("delta").greaterThanOrEqualTo(0)).build();

        System.out
                .println(new ArrayElement("pipeline", aggregate.getPipeline()));
    }
}

En hier is de pijplijn gemaakt:

pipeline : [
  {
    '$geoNear' : {
      near : [
        10, 
        10
      ],
      distanceField : 'distance',
      spherical : false,
      uniqueDocs : true
    }
  }, 
  {
    '$project' : {
      name : 1,
      location : 1,
      maximumDistance : 1,
      delta : {
        '$subtract' : [
          '$maximumDistance', 
          '$distance'
        ]
      }
    }
  }, 
  {
    '$match' : {
      delta : { '$gte' : 0 }
    }
  }
]

HTH - Rob.

PS De bovenstaande bouwers gebruiken een pre-release van de 1.2.0-versie van de driver. De code gaat door de build-matrix terwijl ik typ en zou moeten worden vrijgegeven op vrijdag 22 maart 2013.



  1. (knooppunt:71307) [DEP0079] BeëindigingWaarschuwing

  2. Redis + Node.js - hoe haal ik de waarden op?

  3. Multer - hoe om te gaan met bestanden met upload.fields() nadat bestanden zijn ingediend

  4. pymongo.errors.ConnectionFailure:kon geen verbinding maken met localhost:27017:[Errno 111] Verbinding geweigerd