MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Геопространствено $близо до стойността на полето на текущия документ

Да, възможно е. Просто използвате $geoNear вместо. Пазете се от уловките и прочетете внимателно.

Предполагайки, че намерението ви е да съхраните поле като "travelDistance" за да посочите в документа, че всяко такова търсене трябва да бъде "в рамките" на това предоставено разстояние от запитаната точка, за да бъде валидно. След това просто правим заявка и оценяваме условието с $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"
    }
  }}
])

Единствената уловка е, че $geoNear точно като $near ще върне само определен брой документи "близо" на първо място. Можете да настроите това с опциите, но за разлика от общата форма на заявка, това по същество гарантира, че евентуалните върнати резултати ще бъдат по-малко от посочените „най-близки“ числа.

Докато сте наясно с това, това е напълно валидно.

Всъщност това е общият начин за справяне с квалифицирането на това, което е „близо“ в радиус.

Също така имайте предвид „разстоянието“ в зависимост от това как съхранявате координатите. Като наследени координатни двойки, разстоянията ще бъдат в радиани, които вероятно ще трябва да направите математиката, за да ги преобразувате в километри или мили.

Ако използвате GeoJSON, тогава разстоянията винаги се разглеждат в метри, като стандартен формат.

Всички бележки по математика са в документацията.

N.B Прочетете $geoNear документация внимателно. Опции като "spherical" са необходими за "2dsphere" индекси, каквито трябва да имате за координатите в реалния свят. Също така "limit" може да се наложи да се приложи, за да се увеличи над резултата от документа по подразбиране от 100, за по-нататъшно изрязване.

Тъй като в коментарите се споменава пролетно монго, ето основно същото нещо, което е направено за това:

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



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Каква е ползата от файла mongo.lock?

  2. Индексиране на поле, което е в масив от поддокументи

  3. Битката на базите данни NoSQL - Сравняване на функциите NoSQL на MongoDB и MSSQL

  4. Как да експортирате колекция в CSV в MongoDB?

  5. Сравняване на _id на mongoose и низове