0

Am using mongodb 3.0 - If I have a doc like this(simple version):

{
    "_id" : "1",
    "Name" : "Bob",
    "Timestamp" : ISODate("2016-02-22T14:05:04.000Z"),
    "SportingHobbies" : [ 
        {
            "Sport" : "Football",
            "Position" : "Forward",
            "SkillLevel" : 6,
        }, 
        {
            "Sport" : "Football",
            "Position" : "Defender",
            "SkillLevel" : 3,
        }, 
        {
            "Sport" : "Hockey",
            "Position" : "Forward",
            "SkillLevel" : 5,
        }
    ]
}

I am trying to get the SkillLevel for a particular set of criteria. I tried the following:

db.test.find(
    {    
        "Name" : "Bob",
        "Timestamp": {$gte : ISODate('2016-02-22T14:00:00.000Z'), $lte : ISODate('2016-02-22T15:00:00.000Z')},
        "SportingHobbies" : {$elemMatch : {"Sport" : "Football", "Position" : "Forward"}}
    },
    {
        _id: 0,
        'SportingHobbies.$' : 1
    }
    );

The result I get is:

{
    "SportingHobbies" : [ 
        {
            "Sport" : "Football",
            "Position" : "Forward",
            "SkillLevel" : 6,
        }
    ]
}

I just want the SkillLevel value - "SkillLevel" : "6"

I also tried:

db.test.find(
    {    
        "Name" : "Bob",
        "Timestamp": {$gte : ISODate('2016-02-22T14:00:00.000Z'), $lte : ISODate('2016-02-22T15:00:00.000Z')},
        "SportingHobbies.Sport" : "Football", 
        "SportingHobbies.Position" : "Forward"
    },
    {
       _id: 0,
        "SportingHobbies.SkillLevel" : 1
    }
    );

But this brings back all SkillLevels. Result:

{
    "SportingHobbies" : [ 
        {
            "SkillLevel" : "6"
        }, 
        {
            "SkillLevel" : "3"
        }, 
        {
            "SkillLevel" : "5"
        }
    ]
}

Am I on the right track?

This is the closest I got:

var printData = function(doc){
        print(doc.SportingHobbies.SkillLevel);    {
    "SportingHobbies" : [ 
        {
            "Sport" : "Football",
            "Position" : "Forward",
            "SkillLevel" : 6,
        }
    ]
}
    }

var cursor = db.test.aggregate([
    {$match: {    
        "Name" : "Bob",
        "Timestamp": {$gte : ISODate('2016-02-22T14:00:00.000Z'), $lte : ISODate('2016-02-22T15:00:00.000Z')},
        "SportingHobbies" : {$elemMatch : {"Sport" : "Football", "Position" : "Forward"}}
    }},
    {$unwind: '$SportingHobbies'}
    ]);

cursor.forEach(printData);

But again the result was:

6
3
5

I do not want my result to be a collection like this:

{
    "SportingHobbies" : [ 
        {
            "Sport" : "Football",
            "Position" : "Forward",
            "SkillLevel" : 6,
        }
    ]
}

I want my result to be 6.

gpullen
  • 1,093
  • 2
  • 14
  • 28
  • The [positional `$` operator](https://docs.mongodb.org/manual/reference/operator/projection/positional/) in projection, is what you need. Mentioned many times. – Neil Lunn Apr 06 '16 at 11:03
  • Thanks.. but I am not looking for a collection result. I just want the value 6. I will try and use the $ operator in projection for a while and revert back. – gpullen Apr 06 '16 at 11:28
  • No MongoDB query operation with the exception of `.distinct()` is going to return anything other than a BSON Document in some form or another. If you just want to return a "value" of a "property" only, then you still need to reference the path to that property. Pick a duplicate. Either the positional operator you've been missing, or one of the many references to that same statement made over and over. – Neil Lunn Apr 06 '16 at 11:32
  • 1
    @gpullen sadly but there is nothing like this present in mongodb, here are projection operators https://docs.mongodb.org/manual/reference/operator/projection/ but these doesn't fit you needs i think you must have to go to handle it from code side – rummykhan Apr 06 '16 at 11:48
  • Thanks.. I was trying to avoid writing an app but looks like that's my only way – gpullen Apr 06 '16 at 12:00

0 Answers0