0

I am trying to query a User collection with multiple nested objects, and I'm not sure how to properly use the projection operators (e.g. $) as they seem to work for arrays not objects.

Each user has a "booksRecords" object, with multiple book objects (e.g. hc_1_3, hc_1_4, etc). Each book object has a field called currLevel and I am trying to find kids that have at least one book object where currLevel: 'nursery'.

I tried doing User.find({'booksRecords.$.currLevel': 'nursery'}), but that doesn't seem to be working and I wonder what is the correct way to query nested objects?

I checked Querying nested in mongoDB, but it is different from my case as I'm querying nested objects.

[
  //first object
  {
    _id: "xxx",
    booksRecords: {
      hc_1_3: {
        markedRead: false,
        currLevel: "elementary"
      },
      hc_1_2: {
        markedRead: false,
        currLevel: "elementary"
      }
    }
  },
  //second object
  {
    _id: "xyz",
    booksRecords: {
      hc_1_3: {
        markedRead: false,
        currLevel: "elementary"
      },
      hc_1_2: {
        markedRead: false,
        currLevel: "nursery"
      }
    }
  }  
]

2 Answers 2

1

$ projection applies to array only. You need to use $where to evaluate each document:

db.User.find( { $where: function() {
    for (var i=0 in this.booksRecords) {
        if (this.booksRecords[i].currLevel === 'nursery') {
            return true;
        }
    }
    return false;
} }); 
Sign up to request clarification or add additional context in comments.

Comments

0

can you please this:

var userList = db.User.find();
var booksRecordsList={};

while(userList.hasNext()){
    var user = userList.next();
    for(var key in user.booksRecords){

        if ( !( key in booksRecordsList ) ) {
        booksRecordsList[key] = key;
        }
    }
};

db.User.find().forEach(function(doc){
    for (var booksRecord in booksRecordsList){
        var booksRecordItem = doc.booksRecords[booksRecord];
        if(booksRecordItem.currLevel == "nursery"){
            print(tojson(doc));
        }
    }
});

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.