MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

$geoNear correspondendo ao array mais próximo


Primeiramente eu aconselho fortemente que você crie um índice "2dsphere" para sua coleção se você pretende fazer consultas geoespaciais em coordenadas do mundo real.

Certifique-se de descartar outros índices com os quais você possa estar jogando:
db.records.dropIndexes();
db.records.createIndex({ "addresses.loc": "2dsphere" })

Para fazer o que você quer, primeiro dê uma olhada na pequena modificação que também inclui os includeLocs opção para $geoNear
db.records.aggregate([
  { "$geoNear": {
     "near": [ -73.9815103, 40.7475731 ],
     "spherical": true,
     "distanceField": "distance",
     "includeLocs": "locs"
  }}
])

Agora você verá uma saída que se parece com isso:
{
        "_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
        ]
}

Então, o que isso retornou não foi apenas a distância até o ponto mais próximo, mas "qual" localização foi a partida usada.

Então, se você quiser $filter a matriz original para retornar o mais próximo, então você pode:
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 isso retorna a matriz apenas com essa correspondência:
{
        "_id" : ObjectId("592d0c78555a7436b0883960"),
        "userid" : 7,
        "addresses" : [
                {
                        "apporx" : 50,
                        "loc" : [
                                -73.98137109999999,
                                40.7476039
                        ]
                }
        ],
        "distance" : 0.0000019174641401278624,
        "locs" : [
                -73.98137109999999,
                40.7476039
        ]
}