2012-01-05 17 views
2

私はmongooseとnode.jsを使ってmongodbデータベースにアクセスしています。私は数字に基づいて各結果をバンプアップしたい(バンプしていなければ作成された日付順)。例えば:これは(データベース内のすべてのエントリを反復することなく)達成することができるどのようにC、A、D、B.:mongodb/mongooseクエリの結果パラメータに基づいてパラメータを変更する方法はありますか?

{ name: 'A', 
    bump: 0 }, 

{ name: 'B', 
    bump: 0 }, 

{ name: 'C', 
    bump: 2 }, 

{ name: 'D', 
    bump: 1 } 

順にretreivedだろうか?

+0

だから、1、2、1、0に従ってソートしたいですか? – glortho

+0

いいえ、私はその結果を "ぶつかって"多くの結果を得たいと思います – sdfadfaasd

+0

例を挙げてください... "私はxをデータベースに保存しています...リクエストが入ってきました...私はそれにyをしたい..." –

答えて

1

さんは、その後、私はどうなる(配列がある)あなたのコードは、変数responseある推測してみましょう:

response.sort(function(obj1, obj2){ 
    return obj2.bump - obj1.bump; 
}); 

をしたりも心の名前順に取りたい場合:

response.sort(function(obj1, obj2){ 
    var diff = obj2.bump - obj1.bump; 
    var nameDiff = (obj2.name > obj1.name)?-1:((obj2.name < obj1.name)?1:0); 
    return (diff == 0) ? nameDiff : diff; 
}); 
+0

あなたの最初の人物はC D A BではなくC D Bを返します。彼はバンプに応じてドキュメントを移動したい - AとBの両方に0バンプがあるので、Cは2つのバンプを持つので、Aの上に2つ上がるので、この時点でリストはC A B Dになります。しかし、Dは1つのバンプを持つので、Bの上に1つ上がるので、最終的なリストはC A D Bです。 – glortho

+0

@Jed彼は間違ってそれを書いていたと思います。そして私の答えは、 "注文"としてバンプを解釈している... –

+0

これはリストを繰り返すことはありませんか?私は明らかにMongoDBの専門家ではありませんが、反復せずにどの言語でリストをソートするかはわかりません。 – gilly3

1

純粋にクエリベースのソリューションがドキュメント・スキーマで可能ではないと思います(createdDatebumpフィールドがあると仮定します)。代わりに、私はあなたの希望検索順序を追跡するsortorderと呼ばれる単一のフィールドを示唆:

  1. sortorderが最初に作成タイムスタンプです。 「バンプ」がない場合は、このフィールドでソートすると正しい順序が得られます。
  2. 「バンプ」がある場合、sortorderは無効になります。したがって、単にsortorderの値を修正するだけです。「バンプ」が発生するたびに、バンプされたドキュメントのsortorderフィールドとその直前のドキュメントを交換してください。これは、文字通りソート順にドキュメントを「バンプする」。
  3. クエリするときは、sortorderで並べ替えます。

彼らは他の場所で使用されていない場合は、フィールドbumpcreatedDateを削除することができます。


ほとんどのソーシャルサイトは、投票数(または「バンプ」)に基づいて投稿の表示位置を直接操作しません。代わりに、得票数はスコアを計算するために使用されます。次に、このスコアによって投稿がソートされて表示されます。あなたの場合、createdDatebumpsとを組み合わせて、の単一のスコアにする必要があります。

このサイト(StackOverflow.com)には、「ホット」質問の決定方法に関するmeta discussionがありました。私は、新しい式を思いつくための競争さえあったと思う。このメタ質問はまた、2つの他の人気のあるソーシャルニュースサイト、すなわちY Combinator Hacker NewsとRedditによって使用された公式を共有しました。

1

あなたは心地よい答えではありませんが、あなたが求める解決方法は非現実的です。ここに私の提案があります:

  1. OrderPositionプロパティをBumpの代わりにオブジェクトに追加します。

  2. 「バンプ」をイベントと考えてください。これは、イベントハンドラ関数として最もよく表されます。アイテムがビジネスロジックのどのようなトリガーによっても「バンプ」になると、アイテムのコレクションを調整する必要があります。

    var currentOrder = this.OrderPosition 
    this.OrderPosition = currentOrder - bump; // moves your object up the list 
    // write a foreach loop here, iterating every item AFTER the items unadjusted 
    // order, +1 to move them all down the list one notch.  
    

これは、多くの項目を反復必要がない、と私はあなたがそれを阻止しようとしているが、私は安全にあなたの項目の順序の整合性を確保するための他の方法があると思いません知っている - 場合は特に後で道路の下で発生する他の引っ張られたコレクションと比較して。

+0

あなたのアプローチは正しいと思いますが、実装はオフです。あなたがする必要があるのは、先にあるアイテムと場所を入れ替えることだけです。前の項目を見つけるだけでない限り、リストを反復する必要はありません。 – gilly3

+0

@ gilly3単純にリストオブジェクトであって、その中に場所を入れ替えていれば正しいです。しかし、私が理解しているように、持続的コレクションの各アイテムには順序があり、移動されたものがあれば、他のアイテムを調整する必要があります。フィールドを介してオブジェクト自体にこの値を保持することは、各レコードを更新する必要があることを意味します。むしろ非効率的ですが、問題について多くのことを知らなくても、より良い解決策を提供することはできません。 :) –

2

このようなものを試してみてください。スレッドの総数を追跡するカウンタを格納して、それをthread_countと呼びましょう。最初は0に設定されているので、{thread_count:0}のような書類があります。

新しいスレッドが作成されるたびに、修飾子として{$inc : {thread_count:1}}を使用して最初にfindAndModify()を呼び出します。つまり、カウンタを1増加して新しい値を返します。

新しいスレッドを挿入するときに、カウンタの新しい値をドキュメントのフィールドの値として使用します。これをpost_orderとします。

したがって、挿入する各ドキュメントの値は1ずつ大きくなります。だから、効果的に、あなたが照会および順序post_orderによってASCENDINGとして、それはそれらを返しますすることができます

{name:'foo', post_order:1, created_at:... } // value of thread_count is at 1 {name:'bar', post_order:2, created_at:... } // value of thread_count is at 2 {name:'baz', post_order:3, created_at:... } // value of thread_count is at 3 など

:たとえば、あなたが挿入最初の3文書は次のようになります。古いものから新しいものへの順序(または最も新しいものから最も古いものへのDESCENDING)。

スレッドがupvotedになったときにスレッドをソート順に「バンプ」すると、という文書でupdate()を呼び出すことができます。結果ソートの順に1ずつ進めます。 2つのスレッドがpost_orderに同じ値を持つ場合、created_atは最初に来るものを区別します。だから、あなたはpost_order, created_atで並べ替えるでしょう。

post_ordercreated_atにはインデックスが必要です。

関連する問題