2013-10-15 9 views
10

で更新して集約私は多くの類似の構造化文書を収集してきた、文書の二つがMongoDBの

などの入力になります。デフォルトでは

{ 
    "_id": ObjectId("525c22348771ebd7b179add8"), 
    "cust_id": "A1234", 
    "score": 500, 
    "status": "A" 
    "clear": "No" 
} 

{ 
    "_id": ObjectId("525c22348771ebd7b179add9"), 
    "cust_id": "A1234", 
    "score": 1600, 
    "status": "B" 
    "clear": "No" 
} 

のすべての文書のclear"No"

です

Req:status"A"status"B"に属していれば、同じcust_idのすべての文書のスコアを追加する必要があります。 score2000を超えている場合は、同じcust_idを持つすべてのドキュメントについて、属性を"Yes"に更新する必要があります。

予想される出力:

{ 
    "_id": ObjectId("525c22348771ebd7b179add8"), 
    "cust_id": "A1234", 
    "score": 500, 
    "status": "A" 
    "clear": "Yes" 
} 

{ 
    "_id": ObjectId("525c22348771ebd7b179add9"), 
    "cust_id": "A1234", 
    "score": 1600, 
    "status": "B" 
    "clear": "Yes" 
} 

はいため、+ 500 = 2100 1600、および2100> 2000


私のアプローチ: 私だけの集計関数で合計を取得することができたが、更新時に失敗しました

db.aggregation.aggregate([ 
    {$match: { 
     $or: [ 
      {status: 'A'}, 
      {status: 'B'} 
     ] 
    }}, 
    {$group: { 
     _id: '$cust_id', 
     total: {$sum: '$score'} 
    }}, 
    {$match: { 
     total: {$gt: 2000} 
    }} 
]) 

どうすればいいですか?事前に

感謝:)

+0

エラーの発生方法を教えてください。エラーがありましたか? –

+0

それ自体エラーはありませんが、文章で関数を更新して集約するのが難しいことがわかりました。私はmongodbには非常に新しいので、私はcmdでシナリオを試しています。 – Sam

答えて

10

、モンゴシェルを試して、私は最終的に解決策を持っています私の質問。

Psudocode:

# To get the list of customer whose score is greater than 2000 
cust_to_clear=db.col.aggregate(
    {$match:{$or:[{status:'A'},{status:'B'}]}}, 
    {$group:{_id:'$cust_id',total:{$sum:'$score'}}}, 
    {$match:{total:{$gt:500}}}) 

# To loop through the result fetched from above code and update the clear 
cust_to_clear.result.forEach 
(
    function(x) 
    { 
    db.col.update({cust_id:x._id},{$set:{clear:'Yes'}},{multi:true}); 
    } 
) 

あなたは同じ質問に対する任意の別の解決策を持っている場合は、コメントしてください。

5

次の2つの手順でこれを実行する必要があります。

  1. これらの顧客のそれぞれについて200
  2. 、セットよりも大きい合計得点を顧客(cust_id)を特定clearYes

すでに、最初の部分については適切な解決策があります。 2番目の部分は、別のデータベースとして呼び出されるように実装する必要があります(update())。

Psudocode:

# Get list of customers using the aggregation framework 
cust_to_clear = db.col.aggregate(
    {$match:{$or:[{status:'A'},{status:'B'}]}}, 
    {$group:{_id:'$cust_id', total:{$sum:'$score'}}}, 
    {$match:{total:{$gt:2000}}} 
    ) 

# Loop over customers and update "clear" to "yes" 
for customer in cust_to_clear: 
    id = customer[_id] 
    db.col.update(
     {"_id": id}, 
     {"$set": {"clear": "Yes"}} 
    ) 

あなたはすべての顧客のためのデータベースの呼び出しを行う必要がありので、これは理想的ではありません。この種の操作を頻繁に行う必要がある場合は、スキーマを修正して各文書に合計スコアを含めることができます。 (これは、アプリケーションによって維持されなければならないだろう。)この場合、あなたは、単一のコマンドで更新を行うことができますトラブルの多くの後

db.col.update(
    {"total_score": {"$gt": 2000}}, 
    {"$set": {"clear": "Yes"}}, 
    {"multi": true} 
    ) 
+0

こんにちは、ソリューションのおかげで、私は上記のコードを実行しようとしてきました。 1.構文エラー:予期せぬ識別子2.クエリー式に未定義があります。あなたは完全なコードを書いてください。私は実際にmongoDBを初めて使っています。 – Sam

+0

私はpsudocodeをアプリケーションレベルで実装する必要があり、使用しているドライバを指定していないため、psudocodeを使用しました。私はPython(pymongo)版をやっているかもしれないし、おそらくMongoシェルのためのスクリプトを使ってそれを行う方法を考え出すかもしれない。これらのうちどれがより役に立ちますか? – SuperAce99

+0

私はcmdを使ってコードを実行しようとしています。mongoシェルのスクリプトが直接役に立ちそうです。私は、さまざまなシナリオを試して、mongoの機能を探そうとしています。また、cmdが非常にイライラしているので、mongoで作業するには良いUIを提案してください。 – Sam