MapReduce e fazê-lo do lado do cliente será muito lento - você deve usar a estrutura de agregação (nova no MongoDB 2.2).
Pode parecer algo assim:
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 }
])
Observe que o primeiro e o terceiro membros do pipeline parecem idênticos, isso é intencional e necessário. Aqui está o que as etapas fazem:
- transmitir apenas documentos que tenham a tag "bar" ou "hello" neles.
- desenrole a matriz de tags (ou seja, divida em um documento por elemento de tags
- passar apenas as tags exatamente "bar" ou "hello" (ou seja, descartar o restante das tags)
- grupo por título (pode ser também por "$_id" ou qualquer outra combinação do documento original somando quantas tags (de "bar" e "hello") ele tinha
- classifique em ordem decrescente pelo número de tags relevantes
- (opcionalmente) limite o conjunto retornado ao top 10.