34

I am using mongoose to perform CRUD operation on MongoDB. This is how my schema looks.

var EmployeeSchema = new Schema({
      name: String,
      description: {
        type: String,
        default: 'No description'
      },
      departments: []

    });

Each employee can belong to multiple department. Departments array will look like [1,2,3]. In this case departments.length = 3. If the employee does not belong to any department, the departments.length will be equal to 0.

I need to find all employee where EmployeeSchema.departments.length > 0 & if query return more than 10 records, I need to get only employees having maximum no of departments.

Is it possible to use Mongoose.find() to get the desired result?

Blakes Seven
  • 49,422
  • 14
  • 129
  • 135
SharpCoder
  • 18,279
  • 43
  • 153
  • 249
  • similar to this question: http://stackoverflow.com/questions/7811163/how-to-query-for-documents-where-array-size-is-greater-than-one-1-in-mongodb – steampowered Apr 27 '16 at 21:24

4 Answers4

64

Presuming your model is called Employee:

Employee.find({ "departments.0": { "$exists": true } },function(err,docs) {

})

As $exists asks for the 0 index of an array which means it has something in it.

The same applies to a maximum number:

Employee.find({ "departments.9": { "$exists": true } },function(err,docs) {

})

So that needs to have at least 10 entries in the array to match.

Really though you should record the length of the array and update with $inc every time something is added. Then you can do:

Employee.find({ "departmentsLength": { "$gt": 0 } },function(err,docs) {

})

On the "departmentsLength" property you store. That property can be indexed, which makes it much more efficient.

Blakes Seven
  • 49,422
  • 14
  • 129
  • 135
  • 1
    Strange, but first example doesn't works for me. May be this is old solution that not works with new versions or something? – Pumych Mar 05 '16 at 12:41
  • this is an old solution try the answer of https://stackoverflow.com/a/51260864/10251064 – Basil Satti Dec 24 '22 at 10:07
22

By some reason, selected answer doesn't work as for now. There is the $size operator.

Usage:

collection.find({ field: { $size: 1 } });

Will look for arrays with length 1.

Georgiy T.
  • 1,131
  • 11
  • 17
  • 5
    Note that this finds *only* documents where field has exactly one element. – Narretz Feb 21 '19 at 14:00
  • 1
    The question says "greater than 0", it doesn't mean the size must be exactly 1. – Quan Mar 13 '19 at 19:17
  • I went to the mongodb docs to find an edit for this (hoping I could use a $gt or something) but apparently the $size never accepts a range. I hope they change this in the future. – Raphael Morgan Dec 03 '21 at 12:34
1

use can using $where like this:

await EmployeeSchema.find( {$where:'this.departments.length>0'} )
Mohammad Yaser Ahmadi
  • 4,664
  • 3
  • 17
  • 39
-3

If anyone is looking for array length is greater than 1, you can do like below,

db.collection.find({ "arrayField.1" : { $exists: true }})

The above query will check if the array field has value at the first index, it means it has more than 1 items in the array. Note: Array index start from 0.

Rafeeque
  • 845
  • 9
  • 13