MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Récupère les sous-documents par geoNear - MongoDB

L'option sous $geoNear est includeLocs comme suit :

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

La sortie a l'"emplacement" correspondant à la "distance" dans le champ de sortie :

{
    "_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 vous vouliez le sous-document spécifique dans le tableau qui a été utilisé dans la correspondance en détail, vous pouvez continuer avec un filtre en utilisant $redact :

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

Ou dans les versions antérieures à MongoDB 2.6 comme ceci :

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

Vous devez probablement noter que l'utilisation d'objets dans un sous-document n'est pas toujours une solution optimale et n'est généralement pas adaptée à une variété de tâches. Par exemple, si vos données dans le tableau contenaient éventuellement "plusieurs" emplacements qui seraient "près" du point interrogé, alors seul le point singulier "le plus proche" pourrait être mis en correspondance comme ceci.

Ainsi, bien que vous puissiez le faire, il est préférable de considérer comment vous l'utilisez et les résultats que vous attendez. Dans la plupart des cas, les données de localisation doivent être répertoriées dans leur propre document plutôt que dans un tableau de sous-documents, comme c'est le cas ici.