1

I found something relevant on Query for documents where array size is greater than 1 it works fine for find but not does not work for aggregation query... I have following collection of users...

{
    "_id" : ObjectId("5ac8b91482c2345af70d4650"),
    "firstName" : "Clerk",
    "lastName" : "Kent",
    "email" : "clerk@ltc.com",
    "endorsedBy" : [],
    "followings" : [],
    "followers" : [],
    "isAdminEndorsed" : false,
}
{
    "_id" : ObjectId("5ac8ba3582c2345af70d4658"),
    "firstName" : "Bruce",
    "lastName" : "Wayne",
    "email" : "bruce@linkites.com",
    "endorsedBy" : [],
    "followings" : [ 
        ObjectId("5acc97b817c27b258bc9aa1e")
    ],
    "followers" : [],
    "isAdminEndorsed" : false
}
{
    "_id" : ObjectId("5acc97b817c27b258bc9aa1e"),
    "firstName" : "admin",
    "lastName" : "ltc",
    "email" : "superadmin@ltc.com",
    "endorsedBy" : [],
    "followings" : [],
    "followers" : [ 
        ObjectId("5ac8ba3582c2345af70d4658")
    ],
    "isAdminEndorsed" : true
}
{
    "_id" : ObjectId("5ad6ed4b7730923118b399a7"),
    "firstName" : "Batman",
    "lastName" : "tge",
    "email" : "ashishlal95@gmail.com",
    "endorsedBy" : [ 
        ObjectId("5ad6ed4b7730923118b399a7"), 
        ObjectId("5ad6ed4b7730923118b399a7"), 
        ObjectId("5ad6ed4b7730923118b399a7"), 
        ObjectId("5ad6ed4b7730923118b399a7"), 
        ObjectId("5ad6ed4b7730923118b399a7"), 
        ObjectId("5ad6ed4b7730923118b399a7"), 
        ObjectId("5ad6ed4b7730923118b399a7"), 
        ObjectId("5ad6ed4b7730923118b399a7"), 
        ObjectId("5ad6ed4b7730923118b399a7"), 
        ObjectId("5ad6ed4b7730923118b399a7"), 
        ObjectId("5ad6ed4b7730923118b399a7")
    ],
    "followings" : [],
    "followers" : [],
    "isAdminEndorsed" : false
}

I want users list

1) not in logged in user.

2) endorsedBy length should be less than 10.

3) isAdminEndorsed should be false.

4) firstName should match regex 'cle'.

I have tried following query but doesn't work...Is there anything I am missing here...

const user = await User.aggregate([{
$match: {
    _id: {
        $ne: mongoose.Types.ObjectId(req.user.id)
    },
    $and: [{ endorsedBy: { $lt: 10 } }, { isAdminEndorsed: false }]
}
},{
  $project: {
      isFollow: { $in: [mongoose.Types.ObjectId(req.user.id), 
     '$followers'] },
    }
 }])

My output should be

{
    "_id" : ObjectId("5ac8b91482c2345af70d4650"),
    "firstName" : "Clerk",
    "lastName" : "Kent"
}
Ashh
  • 44,693
  • 14
  • 105
  • 132
  • You should use `$size` to check the array size. – Rahul Raj Apr 18 '18 at 10:06
  • @AshishChoudhary It surely does in v3.6. See the code in my answer. Which version of the bd you are using? – Alex Blex Apr 18 '18 at 10:50
  • The `$exists` test absolutely works, and it's still by far the most performant and reliable answer. Making trivial edits and false statements is no grounds for re-opening your question. Actually do what the answer says. The only other answers given in response here are either "copies" of that logic or wrong, as I have already mentioned. Direct duplicate. – Neil Lunn Apr 18 '18 at 11:07

1 Answers1

1

You should check for absence of 10th element in an array. Try this query after appropriate mongoose changes: Remember to make appropriate changes if you don't want case-insensitive search, plus no need of $and operator here.

db.sample.aggregate([
{$match: {
   _id: {$ne: ObjectId("5ac8ba3582c2345af70d4658")},
   isAdminEndorsed: false,
   "endorsedBy.9":{$exists:false},
   firstName:{$regex:"cle", $options:"i"}
 }},
{$project: {
    isFollow: { $in: [ObjectId("5ac8b91482c2345af70d4650"), 
   '$followers'] },
   }
  }
 ])

Output:

{
  "_id" : ObjectId("5ac8b91482c2345af70d4650"),
  "isFollow" : false
}
Rahul Raj
  • 3,197
  • 5
  • 35
  • 55