sql >> Databáze >  >> NoSQL >> MongoDB

MongoDb blízký/geoneární dotaz s proměnnou vzdáleností

Nebudete to moci udělat s normálním dotazem, protože nemůžete dynamicky nastavit vzdálenost na dokument. Od MongoDB 2.4 to můžete udělat s agregačním rámcem, protože přidali operátor geoNear na začátek potrubí.

První fází bude příkaz geoNear, který je velmi podobný příkazu geonear. Výsledkem bude také vzdálenost od zadaného bodu (10,10) k dokumentu.

Ve druhé fázi budeme muset použít operátora projektu k přidání rozdílu mezi polem maximumDistance a vypočítanou vzdáleností geoNear.

Nakonec porovnáme ty dokumenty, které mají kladnou deltu ((max - vzdálenost)> 0).

Zde je kanál využívající Asynchronní ovladač Java pomocné třídy uživatele.

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

A zde je vytvořen kanál:

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.

P.S. Výše uvedení stavitelé používají předběžnou verzi ovladače 1.2.0. Kód prochází při psaní maticí sestavení a měl by být uvolněn do pátku 22. března 2013.



  1. Zkoušel někdo CouchDB a různé offline implementace (PouchDB)?

  2. Jaká je nejlepší strategie pro synchronizaci dat Redis do MySQL?

  3. Stackexchange.redis postrádá podporu WAIT

  4. Použijte mongoexport s --query pro ISODate