1

I have documents like:

{
  "_id" : ...
  "args" : {
    "pos" : [ <x>, <y> ],
     ...
  }
}

I am trying to get the min and max of the <x> and <y> values using the following aggregate pipeline. It runs but I get no values.

db.main.aggregate([
    { '$match': {
        "args.pos": { '$exists': true} }
    },
    { '$project':
        {
            'x': "$args.pos.0",
            'y': "$args.pos.1"
        }
    },
    { '$group':
        {
            '_id': 'pos',
            'xmin': { '$min': '$x' },
            'xmax': { '$max': '$x' },
            'ymin': { '$min': '$y' },
            'ymax': { '$max': '$y' },
            'hits': { '$sum': 1 }
        }
    },
    { '$project': {
        'hits': '$hits',
        'xmin': '$xmin',
        'xmax': '$xmax',
        'ymin': '$ymin',
        'ymax': '$ymax',
        '_id': 0 }
    }
])

And I get the following output:

{
        "result" : [
                {
                        "xmin" : [ ],
                        "xmax" : [ ],
                        "ymin" : [ ],
                        "ymax" : [ ],
                        "hits" : 281
                }
        ],
        "ok" : 1
}

I have tried various different ways to acces the <x> and <y> values, but I'm new at this and obviously I'm missing something. Any help would be appreciated.

I think the issue is that I can't reach into the array. I have tried a the following simpler query with not success either:

 db.main.findOne({'function':'map'},{"arguments.pos":1})
{
        "_id" : ObjectId("5110407a2c8bea0f0d0000ce"),
        "arguments" : {
                "pos" : [
                        -87.90774999999735,
                        42.11036897863933
                ]
        }
}

db.main.findOne({'function':'map'},{"arguments.pos.0":1})
{
        "_id" : ObjectId("5110407a2c8bea0f0d0000ce"),
        "arguments" : {
                "pos" : [ ]
        }
}

 db.main.findOne({'function':'map'},{"arguments.pos[0]":1})
{ "_id" : ObjectId("5110407a2c8bea0f0d0000ce"), "arguments" : { } }

I'm running mongo shell from mongodb 2.2 if that matters.

1 Answer 1

1

You can't use the pos.0 syntax in a projection. In a find you can use the $slice operator instead, but that's not yet allowed in an $project.

However, you can do this another way; using $unwind and another $group to extract the x and y values:

db.main.aggregate([
    {$match: {'args.pos': {$exists: true}}},
    {$unwind: '$args.pos'},
    {$group: {
        _id: '$_id',
        x: {$first: '$args.pos'},
        y: {$last: '$args.pos'}
    }},
    {$group: {
        _id: null,
        xmin: {$min: '$x'},
        xmax: {$max: '$x'},
        ymin: {$min: '$y'},
        ymax: {$max: '$y'},
        hits: {$sum: 1}
    }},
    {$project: {_id: 0, xmin: 1, xmax: 1, ymin: 1, ymax: 1, hits: 1}}
])
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much. I spent hours searching for a way to do this. Learning new stuff everyday :)

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.