sql >> Base de Datos >  >> NoSQL >> MongoDB

MongoDb cerca/consulta geonear con distancia variable

No podrá hacer esto con una consulta normal ya que no puede establecer dinámicamente la distancia por documento. A partir de MongoDB 2.4, puede hacer esto con el marco de agregación, ya que agregaron el operador geoNear al inicio de las canalizaciones.

La primera etapa será geoNear, que es muy similar al comando geonear. Como resultado, también obtendremos la distancia desde el punto especificado (10,10) hasta el documento.

En la segunda etapa, necesitaremos usar el operador del proyecto para agregar la diferencia entre el campo de distancia máxima y la distancia geográfica cercana calculada.

Por último, hacemos coincidir aquellos documentos que tienen un delta positivo ((max - distancia)> 0).

Aquí está la tubería usando el Controlador Java asíncrono Clases auxiliares de .

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()));
    }
}

Y aquí se crea la canalización:

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.

PD Los desarrolladores anteriores utilizan una versión preliminar de la versión 1.2.0 del controlador. El código está pasando por la matriz de compilación mientras escribo y debería publicarse el viernes 22 de marzo de 2013.