Querying internal array size in MongoDB

if username Alex is unique, you can use next code:

db.test.insert({username:"Alex", tags: ['C#', 'Java', 'C++'] });
db.test.aggregate(
  {$match: {username : "Alex"}}, 
  {$unwind: "$tags"},
  {$project: {count:{$add:1}}},
  {$group: {_id: null, number: {$sum: "$count" }}}
);
{ "result" : [ { "_id" : null, "number" : 3 } ], "ok" : 1 }

Now MongoDB (2.6 release) supports $size operation in aggregation.

From the documentation:

{ <field>: { $size: <array> } }

What you want can be accomplished as following with either by using this:

db.users.aggregate(
   [
      {
         $group: {
            _id: "$username",
            tags_count:  {$first: {$size: "$tags" }}
         }
      }
   ]
)

or

db.users.aggregate(
   [
      {
         $project: {
            tags_count: {$size: "$tags"}
         }
      }
   ]
)

I think it might be more efficient to calculate the number of tags on each save (as a separate field) using $inc perhaps or via a job on a schedule.

You could also do this with map/reduce (the canonical example) but that doesn't seem to be be what you'd want.

I'm not sure it's possible to do exactly what you are asking, but you can query all the documents that match a certain size with $size ...

> db.collection.find({ tags : { $size: 3 }});

That'd get you all the documents with 3 tags ...


xmm.dev's answer can be simplified: instead of having interm field 'count', you can sum directly in $group:

db.test.aggregate(
  {$match: {username : "Alex"}}, 
  {$unwind: "$tags"},
  {$group: {_id: null, number: {$sum: 1 }}}
)