0

Model:

var UserSchema = new Schema({
    username: String,
    userLog: [
        {
            name: String,
            logflag: Boolean,
            logTime: Date
        }
    ],
});

mongoose.model('User', UserSchema);

Sample Documents:

{
    "name" : User_1,
    "userLog" : [ 
        {
            "_id" : ObjectId("598ac4ac4cd6945012e3eac9"),   
            "name" : "Start",
            "logflag" : true,
            "logTime" : "06:00"
        }, 
        {
            "_id" : ObjectId("598ac4ac4cd6945012e3eaca"),
            "name" : "Mid Day",     
            "logTime" : "12:00",
            "logflag" : false
        }, 
        {
            "_id" : ObjectId("598ac4ac4cd6945012e3eacb"),
            "name" : "End",
            "logflag" : false,      
            "logTime" : "18:00"
        }
    ]
},
{
    "name" : User_2,
    "userLog" : [ 
        {
            "_id" : ObjectId("5989c1ec498267d015ca33c9"),
            "name" : "Start",
            "logflag" : true,       
            "logTime" : "18:00"
        },
        {
            "_id" : ObjectId("5989c1ec498267d015ca33ca"),
            "name" : "End", 
            "logflag" : true,       
            "logTime" : "06:00"
        }   
    ]
}

I am looking for a query that retrieves Users that have ALL 'logflags' set to true (or NO logflag set to false). The array has variable number of objects.

In the above example, the query would return User_2.

I have tried the following:

User.find({ "userLog.logflag": {$ne: false}})

which does not work.

Any ideas? Thanks!

  • Why would you say it does not work? Because it actually does. This is basically a "multikey" property in that by the referenced path if "any element" matches the condition then it is true. Since the first document contains elements that actually have a `false` value then the condition is `false` and that document does not return. Only the second document can be returned because none of the elements have the `false` value. You don't need `$elemMatch` when there is only one property inside the array to test. And you don't need `$not` to negate an assertion that is already negative. – Neil Lunn Aug 17 '17 at 22:42
  • @NeilLunn, you are quite right, it does work. My mistake. What does not work for me is using the same query with User.update – AustinOsti Aug 18 '17 at 04:36

1 Answers1

1

You have to change your query

User.find({ "userLog": {$elemMatch: { logflag: true}}})
ManishKumar
  • 1,476
  • 2
  • 14
  • 22
  • The above query isn't the desired one. Because it will pull users who may even have array elements "logflag: false" along with "logflag: true". The expected result in original question is "User_2" but this will give both "User_1" and "User_2". – dilsingi Aug 17 '17 at 17:17
  • your observation is quite right @dilsingi. – AustinOsti Aug 17 '17 at 18:23