MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

$geoNear corrispondente all'array più vicino

In primo luogo, ti consiglio vivamente di creare un indice "2dsphere" per la tua raccolta se intendi eseguire query geospaziali su coordinate del mondo reale.

Assicurati di eliminare altri indici con cui potresti aver giocato:

db.records.dropIndexes();
db.records.createIndex({ "addresses.loc": "2dsphere" })

Per fare ciò che vuoi, dai un'occhiata prima alla leggera modifica che include anche includeLocs opzione per $geoNear

db.records.aggregate([
  { "$geoNear": {
     "near": [ -73.9815103, 40.7475731 ],
     "spherical": true,
     "distanceField": "distance",
     "includeLocs": "locs"
  }}
])

Ora vedrai un output simile a questo:

{
        "_id" : ObjectId("592d0c78555a7436b0883960"),
        "userid" : 7,
        "addresses" : [
                {
                        "apporx" : 50,
                        "loc" : [
                                -73.98137109999999,
                                40.7476039
                        ]
                },
                {
                        "apporx" : 15,
                        "loc" : [
                                -73.982002,
                                40.74767
                        ]
                },
                {
                        "apporx" : 10,
                        "loc" : [
                                -73.9819567,
                                40.7471609
                        ]
                }
        ],
        "distance" : 0.0000019174641401278624,
        "locs" : [
                -73.98137109999999,
                40.7476039
        ]
}

Quindi ciò che ha restituito non è stata solo la distanza dal punto più vicino, ma "quale" posizione era la corrispondenza utilizzata.

Quindi, se vuoi $filter l'array originale per restituire il più vicino, quindi puoi:

db.records.aggregate([
  { "$geoNear": {
     "near": [ -73.9815103, 40.7475731 ],
     "spherical": true,
     "distanceField": "distance",
     "includeLocs": "locs"
  }},
  { "$addFields": {
    "addresses": {
      "$filter": {
        "input": "$addresses",
        "as": "address",
        "cond": { "$eq": [ "$$address.loc", "$locs" ] }
      }
    }
  }}
])

E questo restituisce l'array con solo quella corrispondenza:

{
        "_id" : ObjectId("592d0c78555a7436b0883960"),
        "userid" : 7,
        "addresses" : [
                {
                        "apporx" : 50,
                        "loc" : [
                                -73.98137109999999,
                                40.7476039
                        ]
                }
        ],
        "distance" : 0.0000019174641401278624,
        "locs" : [
                -73.98137109999999,
                40.7476039
        ]
}