lets say I have 1000 documents where each one has:
user_id
text
Now, I would like to pull all those documents but first pull the documents from a few specific users (given an array of user ids) and then all the rest.
I was thinking to use map reduce to create a new weight inline attribute if the user_id exists in the specific users array (using scope to pass the array) and then to sort that new attribute. But from what I could understand, you can not sort after map reduce.
Any one has a good suggestion how to pull this off? Any suggestion will be welcome.
Thanks!
Well there isn't a lot of detail here, but I can give a sample case for consideration. Consider the following set of documents:
{ "user" : "fred", "color" : "black" }
{ "user" : "bill", "color" : "blue" }
{ "user" : "ted", "color" : "red" }
{ "user" : "ted", "color" : "black" }
{ "user" : "fred", "color" : "blue" }
{ "user" : "bill", "color" : "red" }
{ "user" : "bill", "color" : "orange" }
{ "user" : "fred", "color" : "orange" }
{ "user" : "ted", "color" : "orange" }
{ "user" : "ally", "color" : "orange" }
{ "user" : "alice", "color" : "orange" }
{ "user" : "alice", "color" : "red" }
{ "user" : "bill", "color" : "purple" }
So suppose you want to bubble the items for the users "bill" and "ted" to the top of your results, then everything else sorted by the user
and the color
. What you can do is run the documents through a $project stage in aggregate, as follows:
db.bubble.aggregate([
// Project selects the fields to show, and we add a weight value
{$project: {
_id: 0,
"user": 1,
"color": 1,
"weight": {$cond:[
{$or: [
{$eq: ["$user","bill"]},
{$eq: ["$user","ted"]}
]},
1,
0
]}
}},
// Then sort the results with the `weight` first, then `user` and `color`
{$sort: { weight: -1, user: 1, color: 1 }}
])
So what that does is conditionally assign a value to weight
based on whether the user
was matched to one of the required values. Documents that do not match are simply given a 0
value.
When we move this modified document on to the $sort phase, the new weight
key can be used to order the results so the "weighted" documents are on top, and anything else will then follow.
There a quite a few things you can do to $project a weight in this way. See the operator reference for more information:
http://docs.mongodb.org/manual/reference/operator/aggregation/