2016-01-27 14 views
9

Desidero pubblicare una raccolta, in cui i documenti vengono valutati in base a una combinazione dei loro campi e del contesto determinato dall'utente; e il risultato restituito viene ordinato in base a questo punteggio e probabilmente limitato ai risultati principali.Meteor: pubblica una raccolta ordinata in base al punteggio personalizzato

This mostra come aggiungere un filtro transform su una raccolta al momento della pubblicazione. Tuttavia, non sono sicuro che

Infine, sarebbe fantastico usare la mappa di Mongo ridurre per restituire rapidamente gli articoli consigliati in base al calcolo punteggio, che può essere fatto in parallelo.

@ brett-mclain pointed out come alcune mappe riducono l'ordinamento può essere fatto in puro Mongo. Ci sono alcuni pacchetti Meteorout there per estendere le raccolte Meteor, ma non sono riuscito a trovare come utilizzarli nella pubblicazione Meteor (vs in un metodo) Inoltre, here la mappa riduce l'output è inviato a un'altra raccolta che è apparentemente sovrascritta ogni volta il metodo è chiamato.

Qui è più o meno la logica mi piacerebbe realizzare:

/* Server */ 
Meteor.publish('getRecommendedItems', function() { 
    var u = Users.findOne(this.userId); 
    var scoreItem = function(item, u) { ... }; 
    return Items.find(
    {}, 
    { 
     transformInParallel: function(doc) { 
     doc.score = scoreItem(doc); 
     }, 
     sort: {score: -1}, 
     limit: 10, 
    } 
); 
}); 


/* Client template*/ 
Template.templateName.onCreated(function() { 
    this.subscribe('getRecommendedItems'); 
    this.items = Items.find({}, sort: {score: -1}); 
}); 

dove mi salvo score sia accessibile nel client senza fare alcun calcolo lì.

Sembra più facile fare cose personalizzate in Meteor.methods, ma Meteor.publish sembra il posto naturale per farlo; perché è dove si svolge la magica reattività di Meteor.

+0

Possibile duplicato di [Ordinamento mongodb per algoritmo di reddit reddit] (http://stackoverflow.com/questions/22728668/sorting-mongodb-by-reddit-ranking-algorithm) –

+1

L'ho contrassegnato come duplicato e collegato ad una domanda di stackoverflow sull'implementazione dell'algoritmo di decadimento del tempo di reddit mediante l'ordinamento in MongoDB. La loro soluzione è di ridurre la mappa: http://stackoverflow.com/questions/22728668/sorting-mongodb-by-reddit-ranking-algorithm –

+0

Questo è un post molto interessante. Mi sto chiedendo come posso fare quelle operazioni di mongo all'interno del framework di Meteor. La mia comprensione è che Meteor aggiunge un livello che fornisce aggiornamenti in tempo reale al client e, a quanto pare, limita l'operazione che si può fare per ottenere questo risultato. Da una collezione di Meteor, si nota come '.mapReduce' Fammi sapere se mi manca qualcosa, altrimenti modifico e riapro la domanda – Guig

risposta

0
transformInParallel: function(doc) { 
    doc.score = scoreItem(doc); 
    }, 
    sort: {score: -1}, 
    limit: 10, 

Questo si tradurrà in una scansione completa del database.

Le soluzioni a decadimento temporale, che in realtà sono domande di test di programmazione comuni, non sono realmente appropriate per il vostro caso d'uso.

Se la scala è piccola, semplicemente Precompute una serie completa di

{score: ..., userId: ..., item: ...} 

documenti in una raccolta differenziata. Gli indici per un miliardo di piccoli documenti come questi si adatteranno interamente alla RAM di un singolo database server; questo sarà adatto al massimo per es. 30.000 articoli e 30.000 utenti.

Se le tue esigenze superano questo, devi pensare a quale parte del calcolo del punteggio può essere condivisa tra gli utenti. Se nessuna parte del calcolo può essere condivisa, dovresti leggere come Facebook implementa i social graph sui database convenzionali.

Problemi correlati