MapReduce i robienie tego po stronie klienta będzie zbyt wolne - powinieneś użyć frameworka agregacji (nowość w MongoDB 2.2).
Może to wyglądać mniej więcej tak:
db.collection.aggregate([
{ $match : { "tags": { "$in": ["bar", "hello"] } } },
{ $unwind : "$tags" },
{ $match : { "tags": { "$in": ["bar", "hello"] } } },
{ $group : { _id: "$title", numRelTags: { $sum:1 } } },
{ $sort : { numRelTags : -1 } }
// optionally
, { $limit : 10 }
])
Zauważ, że pierwszy i trzeci element potoku wyglądają identycznie, jest to celowe i potrzebne. Oto, co robią kroki:
- przekazuj tylko te dokumenty, które mają w sobie tag „bar” lub „hello”.
- rozwiń tablicę tags (co oznacza podzielenie na jeden dokument na element tags
- przekaż tylko tagi dokładnie „bar” lub „hello” (tj. odrzuć resztę tagów)
- grupuj według tytułu (może to być również „$_id” lub dowolna inna kombinacja oryginalnego dokumentu, dodając, ile tagów (z „bar” i „hello”) miał
- sortuj w porządku malejącym według liczby odpowiednich tagów
- (opcjonalnie) ogranicz zwrócony zestaw do pierwszej dziesiątki