2016-04-16 7 views
1

私はMongoDB mapReduceを使用してランキングアルゴリズムをコーディングしていますが、これはほとんど機能しますが、実装する最新のものはページングです。 map reduceは結果の制限をサポートしますが、どのようにしてオフセット(スキップ)を実装することができますか?私はマングースを使用していることを知って、結果の最新の見た_idに?ランキングアルゴリズム用のマングースmapReduceのページ付け

これは私が書いた手順です:

o = {}; 

o.map = function() { 
    //log10(likes+comments)/elapsed hours from the post creation 
    emit(Math.log(this.likes + this.comments + 1)/Math.LN10/Math.abs((now - this.createdAt)/6e7 + 1), this); 
}; 

o.reduce = function(key, values) { 
    //sort the values, when they have the same score 
    values.sort(function(a, b) { 
     a.createdAt - b.createdAt; 
    }); 

    //serialize the values, because mongoose does not support multiple returned values 
    return JSON.stringify(values); 
}; 

o.scope = {now: new Date()}; 
o.limit = 15; 

Posts.mapReduce(o, function(err, results) { 
    if (err) return console.log(err); 
    console.log(results); 
}); 

をまた、それが進むべき道ではないのMapReduceは、あなたがこのような何かを実装する方法には、他の提案ですか?

答えて

2

あなたが必要とするのは、あなたが言った最新のIDではなく、ソートプロパティであるページ区切り文字です。この場合、式Math.log(this.likes + this.comments + 1)/Math.LN10/Math.abs((now - this.createdAt)/6e7 + 1)と思われます。

したがって、mapReduce queryには、上記の式の値whereを保持する必要があります。または、具体的には、 'formula> = . And also it needs to hold the value of createdAt at the last page, since you don't sort by that. (Assuming createdAt is unique). So yourクエリof mapReduce would sayここで:theFormulaExpression、createdAt:{$ lt:lastCreatedAt}'

複数の同一のcreatedAt値を許可する場合は、データベース自体の外で少し再生する必要があります。

あなたは数式で検索します。

理想的には、それはあなたに正確にその値を持つ要素を与え、次の要素はそれ以降にソートされます。したがって、モジュール呼び出し側に返信するには、この最初の要素を配列から削除します(そして、実際には結果が必要であることを確認してください)。

ここで、複数の類似した値を使用できるようになるため、別のプロペラ、たとえばオブジェクトIDまたはcreated_atが必要です。あなたの消費者(このモジュールの呼び出し元)は両方を提供する必要があります(last value of the scorecreatedAt of the last object)。ページがちょうど途中で分割されているとします.1つ以上のオブジェクトが前のページにあり、別のオブジェクトが次のページにあるとします。 上位の値を削除するだけではなく(同じスコアが既に前のページに表示されているため)、上位から複数のスコアを削除する必要があります。

は本当にになります。ページ全体が既に配信されている可能性があるため、_idsを比較して、モジュールの呼び出し元が提供したものの後に最初のものを探します。または、データを調べてそこにある一致する値の数を確認し、mapReduceからさらに多くの値を取得してから実際のページサイズを取得してみてください。

これ以外にも、私は集約でこれを行うでしょう。それははるかに前もって行うべきです。