1

I have documents with GeoJSON points and I want to count them by "square" using the coordinates. In order to do this I subtract my latitude/longititude with the modulus of the same latitude/longitude and the dimension of the square.

I got an error :

"errmsg" : "$mod only supports numeric types, not Array and NumberDouble"

I don't understand because I use the dot notation to extract the latitude and the longitude. Why does it say it's an array ?

I had no problem using the same query but with coordinates stored into two different properties instead of inside the same array.

Example document :

{
"_id" : ObjectId("560dcd15491a065d6ab1085c"),
"nodeLoc" : 
    {
        "type" : "Point",
        "coordinates" : 
        [
                2.352221,
                48.856612
        ]
    }
}

Aggregation :

db.collection.aggregate(
        [ 
            {
                $group:
                {
                    _id:
                    {
                        latGroup: {$subtract: ["$nodeLoc.coordinates.1", {$mod: ["$nodeLoc.coordinates.1", 0.5]}]},
                        lonGroup: {$subtract: ["$nodeLoc.coordinates.0", {$mod: ["$nodeLoc.coordinates.0", 0.5]}]},
                    },
                    count: {$sum: 1}
                }
            }
        ]
    )

I expect a result like this :

latGroup : 2 lonGroup : 48,5 count : 1
...

Thanks in advance

1 Answer 1

1

Starting from MongoDB 3.2, you can use the $arrayElemAt operator to return an element at a specific index.

db.collection.aggregate([ 
    { "$group": { 
        "_id": { 
            "latGroup": { 
                "$subtract": [ 
                    { "$arrayElemAt": [ "$nodeLoc.coordinates", 1 ] }, 
                    { "$mod": [
                        { "$arrayElemAt": [ "$nodeLoc.coordinates", 1 ] }, 
                        0.5  
                    ]} 
                ] 
            }, 
            "longGroup": { 
                "$subtract": [ 
                    { "$arrayElemAt": [ "$nodeLoc.coordinates", 0 ] }, 
                    { "$mod": [
                        { "$arrayElemAt": [ "$nodeLoc.coordinates", 0 ] },
                        0.5  
                    ]} 
                ] 
            }  
        }, 
        "count": { "$sum": 1 } 
    }}
])

From MongoDB version <= 3.0, you need to de-normalize the "coordinates" array then first $group by _id" and use the $first and $last accumulator which respectively return the first and last value in the "coordinates" array. From there, you can easily regroup your documents using the $mod operator.

db.collection.aggregate([
    { "$unwind": "$nodeLoc.coordinates" }, 
    { "$group": { 
        "_id": "$_id",  
        "latGroup": { "$first": "$nodeLoc.coordinates" }, 
        "longGroup": { "$last": "$nodeLoc.coordinates" } 
    }}, 
    { "$group": {
        "_id": { 
            "latgroup": { 
                "$subtract": [ 
                    "$latGroup", 
                    { "$mod": [ "$latGroup", 0.5 ] } 
                ] 
            }, 
           "lonGroup": { 
               "$subtract": [ 
                   "$longGroup", 
                   { "$mod": [ "$longGroup", 0.5 ] } 
               ] 
           }
        },
        "count": { "$sum": 1 }
    }}
])
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.