MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Dane geoprzestrzenne $w obrębie bieżącej wartości pola dokumentu

Tak, to możliwe. Wystarczy użyć $geoNear zamiast. Uważaj na haczyki i uważnie czytaj.

Zakładając, że Twoim zamiarem jest przechowywanie pola takiego jak "travelDistance" aby wskazać na dokumencie, że wszelkie takie wyszukiwania muszą znajdować się „w” podanej odległości od żądanego punktu, aby były ważne. Następnie po prostu pytamy i oceniamy warunek za pomocą $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"
    }
  }}
])

Jedynym haczykiem jest to, że $geoNear tak jak $near w pierwszej kolejności zwróci tylko określoną liczbę dokumentów „w pobliżu”. Możesz to dostroić za pomocą opcji, ale w przeciwieństwie do ogólnego formularza zapytania, zasadniczo gwarantuje to, że ostatecznie zwrócone wyniki będą mniejsze niż określone „najbliższe” liczby.

Tak długo, jak jesteś tego świadomy, jest to całkowicie uzasadnione.

W rzeczywistości jest to ogólny sposób radzenia sobie z kwalifikowaniem tego, co jest „bliskie” w promieniu.

Należy również pamiętać o „odległości” w zależności od tego, jak przechowujesz współrzędne. Jako starsze pary współrzędnych odległości będą podawane w radianach, które prawdopodobnie będziesz musiał wykonać matematycznie, aby przekonwertować je na kilometry lub mile.

Jeśli używasz GeoJSON, odległości są zawsze brane pod uwagę w metrach, jako standardowy format.

Wszystkie notatki matematyczne znajdują się w dokumentacji.

Uwaga Przeczytaj $geoNear dokumentację starannie. Opcje takie jak "spherical" są wymagane dla "2dsphere" indeksy, takie jakie powinieneś mieć dla współrzędnych świata rzeczywistego. Również "limit" może być konieczne zastosowanie w celu zwiększenia wyniku powyżej domyślnego 100 dokumentu w celu dalszego przycinania.

Ponieważ komentarze wspominają o wiosennym mongo, oto w zasadzie to samo:

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. Znajdź dokument z ObjectID w mongoDB

  2. wypychanie obiektu do schematu tablicy w Mongoose

  3. kontynuuj w kursorze.forEach()

  4. MongoDB:Aktualizacja poddokumentu

  5. Jak sprawić, by testy junitowe wykorzystywały osadzone mongoDB w aplikacji springboot?