问题
I'm still a beginner with MongoDB and I'm getting crazy to create a complex (for me) query with it.
So, my model is:
{
email: String,
name: String,
orientation: String,
location: {
country: String,
city: String
},
contacts: {
phone: String,
email: String,
website: String
}
}
Now I created a query like this:
User.aggregate([
{
$group: {
_id: { city: '$location.city', country: '$location.country', orientation: '$orientation' },
count: { $sum: 1 }
}
},
{
$group: {
_id: '$_id.country',
count: { $sum: '$count' },
cities: {
$push: {
city: '$_id.city',
count: '$count'
}
},
orientations: {
$push: {
orientation: '$_id.orientation',
count: '$count'
}
}
}
}
], function(err, results) {
if (err) return next();
console.log(JSON.stringify(results));
});
Unfortunately I receive good data but just in part.
What I wish to have is a record with:
- total users (I don't have it)
- total users in each Country (I have it)
- total users in each City (I have it)
- total users for each orientation (I don't have it, I have total users for each orientation for each city)
- total users for each orientation in each city (I have it)
Currently it return:
[{
"_id": "France",
"count": 1,
"cities": [{
"city": "Maël-Carhaix",
"count": 1
}],
"orientations": [{
"orientation": "a",
"count": 1
}]
}, {
"_id": "United Kingdom",
"count": 4,
"cities": [{
"city": "Bagshot",
"count": 1
}, {
"city": "London",
"count": 3
}],
"orientations": [{
"orientation": "a",
"count": 1
}, {
"orientation": "a",
"count": 3
}]
}]
This is what I would like to have:
"totalUsers": 5,
"countries: [{
"_id": "France",
"count": 1,
"cities": [{
"city": "Maël-Carhaix",
"count": 1
}],
"orientations": [{
"orientation": "a",
"count": 1
}]
}, {
"_id": "United Kingdom",
"count": 4,
"cities": [{
"city": "Bagshot",
"count": 1
}, {
"city": "London",
"count": 3
}],
"orientations": [{
"orientation": "a",
"count": 4
},
{
"orientation": "b" // if exist...
"count: // n...
}]
}]
I think to have changed this query hundreds of times but I'm at the 60% of the opera.
回答1:
For total users you could do:
db.collection.distinct("email").length
For total users for each orientation, you may be able to do this (assuming count in your model is that of unique users):
db.collection.group({
key: {"orientations.orientation": 1 },
reduce: function(cur, result) { result.count += cur.count },
initial: { count: 0 }
})
In the future, as Niel has already mentioned, it's best to provide the full model (even if you input fake data) so that we can help you and write answers that actually make sense.
来源:https://stackoverflow.com/questions/27799780/mongodb-query-should-return-many-information