2016-08-25 6 views
13

私のコレクションの1つは、ステータスのある操作(またはタスク)のリストです。例えば、文書のリストは、私がnew > pending > complete彼らの状況に基づいて、このリストをソートしたいこのMongoDBがカスタム式または関数を使用してソートする

{ 
    _id: '57befe57fc956d2e3252890c', 
    task: 'Go buy milk', 
    status: 'pending' 
}, 
{ 
    _id: '57befe5efc956d2e3252890d', 
    task: 'Cook dinner', 
    status: 'complete' 
}, 
{ 
    _id: '57befe5efc956d2e3252890e', 
    task: 'Play games', 
    status: 'new' 
} 

のように見えることができます。

余分なフィールドを作成せずにMongoDBでどうすればいいですか?私の場合、ソート順はあらかじめ設定されていても構いません(ユーザは例えばpending > new > completeに設定することができます)。

+0

あなたがトンを処理できない理由として理由があります彼はクライアント側でソートしていますか? 最善の策は、すべての文書を返し、その後、ユーザーの優先順位に基づいて、サブグループを作成するためにフィルタを使用することです https://lodash.com/docs#filterあなたは、2つのパイプラインを持つ集約パイプラインでこれを行うことができ – dyouberg

+1

、 '$ project'と' $ sort'です。 '$ project'は余分なフィールドを作成します。たとえば' $ cond'演算子であらかじめ設定された順序に基づいて 'score'が生成されます。例えば' status'の上記スコアの場合、 "new"は3になりますpending 2などの場合、 '$ sort'パイプラインはscoreフィールドをソートします。 – chridam

+1

@dyouberg私はページネーションを使用しています。サーバー側で '$ limit'より前にソートする必要があります。そうしないと、ページネーションがすべて乱れてしまいます。なぜすべてのアイテムをクライアントにダウンロードすることをお勧めしますか?これは帯域幅と処理の悪い使用です。 –

答えて

6

@chirdamは実装がどのように見えるかに基づいています。また、新しい並べ替えフィールドは、要求されたとおりに結果に存在しません。

のDataSet:

{ 
    _id: '57befe57fc956d2e3252890c', 
    task: 'Go buy milk', 
    status: 'pending' 
}, 
{ 
    _id: '57befe5efc956d2e3252890d', 
    task: 'Cook dinner', 
    status: 'complete' 
}, 
{ 
    _id: '57befe5efc956d2e3252890e', 
    task: 'Play games', 
    status: 'new' 
} 

問合せ:

db.task.aggregate([ 
    { "$project" : { 
     "_id" : 1, 
     "task" : 1, 
     "status" : 1, 
     "order" : { 
      "$cond" : { 
       if : { "$eq" : ["$status", "new"] }, then : 1, 
       else : { "$cond" : { 
        "if" : { "$eq" : ["$status", "pending"] }, then : 2, 
        else : 3 
        } 
       } 
      } 
     } 
    } }, 
    {"$sort" : {"order" : 1} }, 
    { "$project" : { "_id" : 1, "task" : 1, "status" : 1 } } 
]) 

出力:

{ "_id" : "57befe5efc956d2e3252890e", "task" : "Play games", "status" : "new" } 
{ "_id" : "57befe57fc956d2e3252890c", "task" : "Go buy milk", "status" : "pending" } 
{ "_id" : "57befe5efc956d2e3252890d", "task" : "Cook dinner", "status" : "complete" } 
+0

既存のフィールドをもう一度追加したくない場合は、プロジェクトの代わりに[$ addFields](https://docs.mongodb.com/manual/reference/operator/aggregation/addFields/)を使用することができます。 – mido

+3

複数のif-then-elseシーケンスではなく、配列に必要な順序を入れ、 "$ indexOfArray"式を使用して並べ替えフィールドを生成できます。ここに例があります:http://www.kamsky.org/stupid-tricks-with-mongodb/using-34-aggregation-to-return-documents-in-same-order-as-in-expression –

+0

@AsyaKamskyあなたそれを答えとして加えるべきです。私は人々があなたのコメントを逃すことができると確信しており、それはかなり良い解決策です。 –

関連する問題