sql >> Base de Datos >  >> NoSQL >> MongoDB

Obtiene subdocumentos por geoNear - MongoDB

La opción debajo de $geoNear es includeLocs de la siguiente manera:

Store.aggregate([
    { "$geoNear": {
        "near": [ -70.64341379999999, -33.4268697 ],
        "distanceField": "distance", 
        "maxDistance": 0.0900899926955034,
        "includeLocs": "location"
    }}
])

La salida tiene la "ubicación" coincidente con la "distancia" en el campo de salida:

{
    "_id" : ObjectId("5507b18d1c3bdce0535aecd0"),
    "name" : "store1",
    "branchoffices" : [
            {
                    "name" : "bo1",
                    "location" : [
                            -70.64341379999999,
                            -33.4268697
                    ]
            },
            {
                    "name" : "bo2",
                    "location" : [
                            80.4,
                            43.3
                    ]
            }
    ],
    "distance" : 0,
    "location" : [
            -70.64341379999999,
            -33.4268697
    ]
}

Si quería el subdocumento específico en la matriz que se usó en la coincidencia con todos los detalles, entonces podría continuar con un filtro usando $redact :

Store.aggregate([
    { "$geoNear": {
        "near": [ -70.64341379999999, -33.4268697 ],
        "distanceField": "distance", 
        "maxDistance": 0.0900899926955034,
        "includeLocs": "location"
    }},
    { "$redact": {
        "$cond": [
            { "$eq": [ "$location", "$$ROOT.location" ] },
            "$$DESCEND",
            "$$PRUNE"
        ]
    }}
])

O en versiones anteriores a MongoDB 2.6 así:

Store.aggregate([
    { "$geoNear": {
        "near": [ -70.64341379999999, -33.4268697 ],
        "distanceField": "distance", 
        "maxDistance": 0.0900899926955034,
        "includeLocs": "location"
    }},
    { "$unwind": "$branchoffices" },
    { "$project": {
        "name": 1,
        "branchoffices": 1,
        "matched": {
            "$eq": [ "$location", "$branchoffices.location" ]
        }
    }},
    { "$match": { "matched": 1 } },
    { "$group": {
        "_id": "$_id",
        "name": { "$first": "$name" },
        "branchoffices": { "$push": "$branchoffices" },
        "distance": { "$first" "$distance" }
    }}
])

Probablemente debería tener en cuenta que el uso de objetos dentro de un subdocumento no siempre es una solución óptima y generalmente no es adecuado para una variedad de tareas. Por ejemplo, si sus datos en la matriz posiblemente contenían ubicaciones "múltiples" que estarían "cerca" del punto consultado, entonces solo el punto singular "más cercano" podría coincidir de esta manera.

Entonces, aunque puede hacer esto, es mejor considerar cómo lo está usando y los resultados que espera. En la mayoría de los casos, los datos de ubicación deben enumerarse en su propio documento en lugar de en una matriz de subdocumento como se hace aquí.