2016-06-28 4 views
4

私はモンゴDBで問題の解決策を見つけることに苦労しています:のMongoDB - ソートする計算フィールドによって

私は高い書き込み/読み込み比率で、コレクションのクエリを実行する必要があります。 クエリは、同じドキュメントに属する他の フィールドから派生したフィールドでドキュメントをソートすることにあります。 さらに、これらのフィールドの1つは配列のサイズであり、それによってさらに難しくなります。

簡単な例:

D1 - { _id: 1, field: 1, array_field: [a,b,c,d] } -> score = 1 + 4 = 5 
D2 - { _id: 2, field: 2, array_field: [a,b] }  -> score = 2 + 2 = 4 

期待される結果:

D1 - { _id: 2, score: 4 } 
D2 - { _id: 1, score: 5 } 

(スコアが結果セットでは必要ありません)私がこれまで試した

ソリューション:

  1. A ddは一貫して更新される文書のフィールドとしてのスコアで、他のフィールドは更新されます。問題:

    • スコアが計算された後、クエリ(チューニング)をパラメータ化することはできません
    • スコア上のインデックスは
  2. 非常に頻繁に更新する必要があるので、それは高価です作業を容易にし、パラメータ化の問題を解決するアグリゲーションパイプラインを作成します。 しかし、パフォーマンスの低下は本当に高いです。mongoは計算フィールドの使用インデックスに依存できず、メモリの問題(100MBのクエリエラー)が発生します。 可能な解決策は、allowDiskUseフラグを有効にすることです。ただし、クエリが遅くなりすぎます。

更新:私は、クエリが約10倍秒に実行されることを指摘したいと思います。したがって、スコアを事前に計算して別の文書に保存することは、実行可能な解決策ではない可能性があります。

原則使用:問題は非常に困難なためです。もう少し詳しく説明しましょう。私は現在、作成日と最終更新日でソートしている投稿の記事(Facebookの記事のようなもの)を持っています。私は、私が話していたスコアで定義されている "熱心さ"によって投稿を並べ替えることができるようにしたいと思います。 abcdはパラメータです

score = a * likes - b * dislikes + c * num_comments + d * (now - creation_date) 

は私が同調するようにアルゴリズムを変更することができます。私は、スコアを計算する興味深い方法は、次のようになることができると考えました。 likesおよびdislikesは、ユーザを参照するObjectIDの配列であり、num_commentsは単純にコメントの数です。 RESTエンドポイントに応答を提供するために照会が実行されます。これ以上の操作は必要ありません:Request-> Query-> Response。

派生フィールドと集約フィールドの経験はありますか? ありがとう!

+1

私が同じような問題に遭遇したとき、私はレポートを遅らせることになりました。集計と$ outを持つ新しいコレクションを作成しました。これは他の書き込みがないので、インデックスを使用して最適化できます。私はそれが最適な解決策であるとは確信していませんが、それは私のために働いていました。 – Tiramisu

答えて

0

複雑な問題のようです。

このクエリは仕事をしますが、パフォーマンスについてお聞きしたいと思います。

db.perlz.aggregate([ 
// {$match:{whatever is needed here}} 
     { 
      $project : { 
       _id : 1, 
       score : { 
        $sum : [{ 
          "$size" : "$array_field" 
         }, "$field"] 
       } 
      } 
     }, { 
      $sort : { 
       score : 1 
      } 
     } 

    ]) 

これがビジー状態のサーバー上で行われているとして、私は、レプリカセットのセットアップを考慮し、スレーブサーバ上でいくつかのクエリを発行することにより、負荷を分散しようとするだろう。あなたの更新を1として

EDIT

これらの手順は、この問題にも適用できることができれば、私は思ったんだけど:同類の2種類を持っている

  1. 更新文書構造: processedおよびnewProcessedのようなものが、likes, dislikes, numCommentsフィールドに影響を及ぼす作業者による文書スコアとセットアップスコアに追加されたようなものです - delta/differenceの値を計算する必要があります。

  2. 前のポイント(事前計算スコア)に基づいて、最小の入力セットを決定しようと

  3. リミット出力ドキュメントの既知量(ページングを実装する)動的フィールドの値を1として

に - スコア値を得るために必要な膨大な計算量はありません。考えられるのは、計算と_idで使用されるフィールドをプロジェクトすることです。その後、$lookupを最後のステージとして使用し、スコアとソート結果を持つmacz親ドキュメントを使用します。

すべての歓迎!

+0

残念ながら、これは私がやったことです。これは、インデックスを使ってソートすることができないので、 '100MBのクエリエラー 'となります。 –

+0

OK、その出力のプロセスの次のステップは何ですか? – profesor79

+0

私はこのような質問が必要な理由について、より多くの文脈で質問を更新しました。 –

関連する問題