1

I would like to return the count of an embedded collection in a query in mongodb.

Say I have a collection called profiles

var ProfileSchema = new Schema({
  uname: {
    type: String,
    required: true,
    index: true,
    unique: true
  },
  fname: String,
  lname: String,
  posts: [ObjectId]
}); 

How can I query it so that I select uname, frame, lame, posts.length ? I don't want to return the posts collection over the wire since users can have hundreds of posts. Should I even embed the post ids in the profile schema? Maybe I should just get rid of it since there is already another collection defined for posts, so I'm essentially using Profile.posts as an embedded collection of foreign keys.

MonkeyBonkey
  • 46,433
  • 78
  • 254
  • 460
  • You can group the the collection by uname and in the reduce function you can count the post objects. Be careful as the group is limited by the keys. If this limitation is a deal breaker you can use map reduce. – peshkira Jun 03 '12 at 12:40
  • hmm you mean in a map reduce function I can put the reduce function in, or in a regular query. Ideally it would be nice to do db.profiles.find({uname:'mike'}, {posts.length:1}) – MonkeyBonkey Jun 03 '12 at 13:05
  • No, in a group function you can have a reduce function. Here is an example, where they implement count with group: http://www.mongodb.org/display/DOCS/Aggregation#Aggregation-Group – peshkira Jun 03 '12 at 13:14
  • but I already have the post items grouped by uname in the profile object's posts property. – MonkeyBonkey Jun 03 '12 at 14:16
  • Embedded collection -> array of embedded documents, yes? – paulmelnikow Jun 04 '12 at 22:45
  • In this case it's actually just an array of strings. So the profile document has a property called posts which is an array of strings. – MonkeyBonkey Jun 05 '12 at 01:26
  • If it's an array of strings why does it say objectID? And what framework are you using, by the way? – paulmelnikow Jun 11 '12 at 20:37
  • mongoose.js, and yes it's an objectID in the example but it could be represented as just an array of strings as well. – MonkeyBonkey Jun 12 '12 at 18:09

1 Answers1

5

See Mongo docs discussion of $size operator here.

In a nutshell, you can query based on exact array size with $size operator, but you can't get back array size, nor can you query based on array size range.

What the suggests would work well for you - keep another field which is the count of posts - that may be used both in queries as a filter/range and you can return it when you need to know how big an array is. Whether the posts are stored elsewhere or embedded in the array, this field would be very useful if you do querying or filtering based on number of posts.

There is a very similar question with similar suggestions.

Community
  • 1
  • 1
Asya Kamsky
  • 41,784
  • 5
  • 109
  • 133