问题
BACKGROUND: I have Posts and Users, both of which HABTM Communities. In my Post model, I have a method for calculating a post's relevance to a given user by comparing how many communities they have in common as such:
def relevance(user)
(self.communities & user.communities).length
end
OBJECTIVE: To query Posts either by a given relevance i.e.
Post.where(:relevance => 3)
or
to query all posts and sort them by relevance i.e.
Post.all.desc(:relevance)
I know that the user variable is needed there somewhere, just wondering if something like this is possible or if a workaround exists.
回答1:
You can do this in mongoDB using Aggregation Framework (new in version 2.2).
You have to have the array of User's communities available. I'll call it userComms in this example - I'm expecting it to be an array with the same type of values that posts.communities are.
db.posts.aggregate( [
{
"$unwind" : "$communities"
},
{
"$match" : {
"communities" : {
"$in" : userComms
}
}
},
{
"$group" : {
"_id" : "$_id",
"relevance" : {
"$sum" : 1
}
}
},
{
"$sort" : {
"relevance" : -1
}
}
]);
This returns a document of the form:
{
"result" : [
{
"_id" : 1,
"relevance" : 4
},
{
"_id" : 6,
"relevance" : 3
},
...
]
}
The result array contains _ids of posts and relevant as computed by adding the number of communities they had in common with user. Then it's sorted (descending) by that sum.
来源:https://stackoverflow.com/questions/12164876/mongoid-query-db-by-virtual-attribute