2016-02-01 16 views
6

でMongoDBのコレクションのために、私は、製品のこのコレクションを持っていると私は私が何をしたいのか、カスタムソート関数に基づいてtop 10 productsは、カスタムの並べ替え流星

[{ _id: 1, title, tags:['a'], createdAt:ISODate("2016-01-28T00:00:00Z") } , 
{ _id: 2, title, tags:['d','a','e'], createdAt:ISODate("2016-01-24T00:00:00Z") }] 

を表示する」に基づいて、それを並べ替えることですマジックスコア "を計算することができます。たとえば、次の式に基づいて:tag_count*5 - number_of_days_since_it_was_created

最初のものは、1日齢である場合、これはスコアを行います

[{_id:1 , score: 4}, {_id:2, score: 10}] 

特に以来、私はこれを実現する方法についていくつかのアイデアを持っていますが、私は彼らがどのように良いかわかりません私はモンゴや流星の両方に新たなんだ:

  1. 、オブザーバー(Meteor.observe)とドキュメントが が変更されるたびに(または作成新しいものを)開始し、スコアを再計算し、それを上 を更新

    コレクション自体。もし私がこれを行うと、私はちょうど$ orderBy 私はそれが必要な使用することができます。

  2. いくつか読んだ後、私はそのMongoの集合体を発見したり をmap_reduce私は同じ結果を達成するのを助けることができますが、私の知る限りが分かったとして、 流星が直接

  3. それをサポートしていないソートのコレクション配列が、私はそれが改ページでどのように動作するかわからないんだけど、この メソッドを使用して、クライアント側

はあなたと共有することができます任意の情報をありがとう(私は、文書の限られた数に加入することを考慮して)私!

+2

実行時にこれを行う唯一の方法は、他の方法でサーバー側をソートする関数を提供できないためです(mapReduceは、計算フィールド上のページングには適していません)。要件を指定する代わりに、フィールドを格納し、毎日それを再計算するだけです(また、更新時にも)。それは単純なスケジュールされたタスクであり、次に既に存在するフィールドの基本的なソートです。また、そのようにパフォーマンスが向上します。 –

+0

それでは、製品のアップデートごとにイベントリスナーを追加するのではなく、ちょっとだけcronを実行する必要がありますか?正直言って、それは理にかなっています、特に私はスコアがリアルタイムである必要はないからです。これを行う方法は、 'cursor.each()'を使うべきでしょうか、それとも良い方法がありますか?私はmongodbでこのようなことができるかどうかは分かっていません。 "UPDATE products SET score = tags_count * 10" 'ここで私は他人の値に基づいてフィールドを設定します。ありがとう@ BlakesSeven –

+0

それはアイデアだった。お客様の要件には「日数」と記載されているため、リアルタイムに必要なようには聞こえません。あらかじめ計算したものを保存することは、確かにここに行く方法のようです。 –

答えて

7

関数リテラルis just being implemented in meteorをソートするので、あなたは、今後のリリースに

Products.find({}, {sort: scoreComparator}); 

ような何かを行うことができるはず。

transform property when creating collectionを使用できます。この変換では、魔法の操作を関数として格納します。

score=function(){ 
    // return some score 
}; 
transformer=function(product){ 
    product.score=score; 
    // one could also use prototypal inheritance 
}; 
Products=new Meteor.Collection('products',{transform:transformer}); 

残念ながら、you cannot yet use the sort operator on virtual fieldsは、ミニゴンでサポートしていないためです。

だから、究極のフォールバックも仮想フィールドの並べ替えも読み書き機能の並べ替えがminimongoでサポートされているときは、述べたように、クライアント側のソートです:

// Later, within some template 
scoreComparator=function(prd1,prd2){ 
    return prd1.score()-prd2.score(); 
} 
Template.myTemplate.helpers({ 
    products:function(){ 
    return Products.find().fetch().sort(scoreComparator); 
    } 
}); 

私はそれがするかどうかはわかりませんページネーションで振る舞う

EDIT(私は、文書の限られた数に加入することを考慮して):スコアは確かに、加入した文書の中で計算されます。