3

I have to mongoDB collection A and B. Both of them have the field 'user'. I would like to know the number of distinct users in A, B, and (A + B). Pseudo code would be like the following:

A.user.distinct().count()
B.user.distinct().count()
(A.user union B.user)..distinct().count()

Can someone give some suggestions?

styvane
  • 59,869
  • 19
  • 150
  • 156
kindadolf
  • 209
  • 1
  • 8

2 Answers2

4

You can't use count() with distinct to get the number of distinct users in your collection because It is not an array method and distinct returns an array. You need to use the Array.length property

To get the number of distinct users in A or B use the following

db.A.distinct('user').length
db.B.distinct('user').length

To get the number of distinct users in A union B use Array.prototype.concat() and Array.prototype.filter()

var users = db.A.distinct('user');
users = users.concat(db.B.distinct('user'));
var num = users.filter(function(u, pos) {return users.indexOf(u) == pos; });
num.length;
styvane
  • 59,869
  • 19
  • 150
  • 156
2

To get the number of distinct users in each collection you can run the following in the mongo shell:

db.A.distinct("user").length;
db.B.distinct("user").length;

To get the number of distinct users in the union of A and B I would first retrieve the distinct arrays for each collection and then do a union of the arrays and find the length. If you're using JavaScript, I would recommend using Underscore.js' union() method to do it. Its usage is explained here. Note that you can load Underscore.js (or any JavaScript file) to the mongo shell by running the following command from within the shell:

load("path/to/underscore.js");

Then you can easily run the following:

var a = db.A.distinct("user");
var b = db.B.distinct("user");
_.union(a, b).length;

Otherwise you can implement your own JavaScript function, as explained here, or one in the language of your application.

Community
  • 1
  • 1
Juan Carlos Farah
  • 3,829
  • 30
  • 42
  • Truly appreciate your descent solution. I am picking Michael9's solution since it is more native (without the need to load other js packages) – kindadolf Mar 01 '15 at 22:20