MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Requête MongoDb near/geonear avec distance variable

Vous ne pourrez pas le faire avec une requête normale car vous ne pouvez pas définir dynamiquement la distance par document. À partir de MongoDB 2.4, vous pouvez le faire avec le cadre d'agrégation car ils ont ajouté l'opérateur geoNear aux débuts des pipelines.

La première étape sera la commande geoNear qui est très similaire à la commande geonear. Nous obtiendrons également la distance entre le point spécifié (10,10) et le document en conséquence.

La deuxième étape, nous devrons utiliser l'opérateur de projet pour ajouter la différence entre le champ maximumDistance et la distance geoNear calculée.

Enfin, nous comparons les documents qui ont un delta positif ((max - distance)> 0).

Voici le pipeline utilisant le pilote Java asynchrone les classes d'assistance 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()));
    }
}

Et voilà le pipeline est créé :

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 Les constructeurs ci-dessus utilisent une pré-version de la version 1.2.0 du pilote. Le code passe par la matrice de construction au fur et à mesure que je tape et devrait être publié d'ici le vendredi 22 mars 2013.