0

Prenez cette requête:

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

Je veux attribuer maxDistance $ la valeur du champ spécifié du document évalué en cours. Est-ce possible?

+0

Non, cela est impossible. –

+1

Vous n'êtes pas le premier avec cette question :) https://stackoverflow.com/questions/39970436/mongo-geowithin-query-using-sphere-radius-from-the-current-document –

+1

@SergioTulentsev Alors vous êtes lire les mauvais messages. Cela a été possible pendant un certain temps. Vous faites juste différemment. –

Répondre

3

Oui, c'est possible. Vous utilisez simplement $geoNear à la place. Méfiez-vous des captures et lisez attentivement. En supposant que votre intention est de stocker un champ tel que "travelDistance" pour indiquer sur le document que de telles recherches doivent être «dans» la distance fournie par rapport au point demandé pour être valide. Ensuite, nous avons simplement interroger et évaluer l'état avec $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" 
    } 
    }} 
]) 

Le seul hic est que $geoNear comme $near renverrons seulement un certain nombre de documents « » en premier lieu. Vous pouvez régler cela avec les options, mais contrairement au formulaire de requête général, cela garantit essentiellement que les résultats retournés seront inférieurs aux nombres "les plus proches" spécifiés.

Tant que vous en êtes conscient, cela est parfaitement valable.

Il s'agit en fait de la manière générale de traiter la qualification de ce qui est «proche» dans un rayon.

Soyez également conscient de la "distance" selon comment vous avez les coordonnées stockées. En tant que paires de coordonnées héritées, les distances seront en radians dont vous aurez probablement besoin pour calculer les kilomètres ou les kilomètres. Si vous utilisez GeoJSON, les distances sont toujours considérées en mètres, comme le format standard.

Toutes les notes de mathématiques sont dans la documentation.

N.B. Lire la documentation attentivement $geoNear. Des options comme "spherical" sont nécessaires pour les index "2dsphere", comme vous devriez l'avoir pour les coordonnées du monde réel. De même, il peut être nécessaire d'appliquer "limit" pour dépasser le résultat du document 100 par défaut, pour un ajustement ultérieur.


Comme les commentaires mentionnent le printemps mongo, alors voici essentiellement la même chose fait pour que:

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" 
      ) 
     ) 
     ); 
    } 
    } 
); 
+0

Ça marche, merci. Mais j'ai un autre problème maintenant, car j'utilise Spring Data Mongodb framework, cela ne supporte toujours pas $ redact https://jira.spring.io/browse/DATAMONGO-931 :( – anat0lius

+1

@LiLou_ Il ne peut pas avoir méthode "helper", mais vous pouvez toujours implémenter votre propre pipeline en tant que résumé en utilisant l'entrée DBObject Plusieurs réponses sur ce site à ce sujet Je sais depuis que j'en ai écrit quelques-unes –

+1

@LiLou_ Ajout de la traduction Spring Data Mongo Comme vous pouvez le constater, ajouter des étapes et des instructions personnalisées est assez simple: –