根據您從您檢索到的信息[R用戶基本上你想出來一個aggregation framework查詢,看起來像這樣:
db.posts.aggregate([
{ "$match": { "user_id": { "$in": [ 673, 8976 ] } } },
{ "$project": {
"user_id": 1,
"post_text": 1,
"weight": {
"$cond": [
{ "$eq": [ "$user_id", 8976 ] },
1,
{ "$cond": [
{ "$eq": [ "$user_id", 673 ] },
4,
0
]}
]
}
}},
{ "$sort": { "weight": -1 } }
])
那麼,爲什麼聚集在這不聚集?正如你所看到的,聚合框架不僅僅是聚合。在這裏它被用來將一個新的領域「投射」到文檔中,並用「權重」來填充它。這使您可以按照您希望排序的值重新排序結果。
當然,您需要以「生成」的方式從您的初始數據中獲取此表單,您可以爲任何數據執行此操作。這需要幾個步驟,但在這裏我將介紹JavaScript的方式來做到這一點,它應該很容易轉換到大多數語言
也假設你的實際「用戶」看起來更像這樣,這將是有效的:
{
"user_id": 123,
"friends": [
{ "user_id": 673, "strength": 4 },
{ "user_id": 8976, "strength": 1 }
]
}
從這樣一個對象,那麼你構建聚合管道:
// user is the structure shown above
var stack = [];
args = [];
user.friends.forEach(function(friend) {
args.push(friend.user_id);
var rec = {
"$cond": [
{ "$eq": [ "user_id", friend.user_id ] },
friend.strength
]
};
if (stack.length == 0) {
rec["$cond"].push(0);
} else {
var last = stack.pop();
rec["$cond"].push(last);
}
stack.push(rec);
});
var pipeline = [
{ "$match": { "user_id": { "$in": args } } },
{ "$project": {
"user_id": 1,
"post_text": 1,
"weight": stack[0]
}},
{ "$sort": { "weight": -1 } }
];
db.posts.aggregate(pipeline);
,這是所有有給它。現在,您有一些代碼可以查看用戶的「朋友」列表,並構建另一個查詢以獲取來自這些朋友的所有帖子,並根據每個朋友的「強度」值進行加權。
當然,你可以通過只刪除或更改$match
,但保持「重」投影,你可以「浮動」所有的「朋友」的帖子在做很多同樣的事情對所有職位查詢最佳。
感謝您的回答,這就是我一直在尋找的,但是有一個問題,這種方法是否經過了優化,並且足夠快,可以同時用於許多用戶? – Kordkandi 2014-09-05 10:19:45
@Kordkandi這裏的實際處理與使用投影字段和'.sort()'的'.find()'操作並沒有太大的不同,它具有計算字段的優勢,否則不可能使用'。找到()'。數據庫服務器應該比應用程序服務器更快,並且您也可以在服務器上限制和分頁結果。如果每個用戶有超過500個「freinds」,那麼你不應該使用數組,而並行查詢是選項。但是這很快,無論20個或更多的朋友看起來有多複雜 – 2014-09-05 10:33:30
非常感謝,你是我日常問題的答案;) – Kordkandi 2014-09-05 10:35:44