2016-04-04 9 views
0

と古いスラッシュエスケープバグがそうのように、いくつかのめちゃくちゃデータを私たちに残さ:

{ 
    suggestions: [ 
     "ok", 
     "not ok /////////// ... 10s of KBs of this ... //////", 
    ] 
} 

私はちょうど配列のうち、これらの不正な値を引くしたいと思います。私の最初のアイデアは、4「/」文字にマッチする正規表現に基づいて$pullにしたが、正規表現が大きな文字列に動作しないことが表示されます:

db.notes.count({suggestions: /\/\/\/\//}) // returns 0 
db.notes.count({suggestions: {$regex: "////"}}) // returns 0 

私の次のアイデアは、ドキュメントを検索する$whereクエリを使用していたことそのクエリが動作する1000より長いsuggestion文字列があります。

db.notes.count({ 
    suggestions: {$exists: true}, 
    $where: function() { 
     return !!this.suggestions.filter(function (item) { 
      return (item || "").length > 1000; 
     }).length 
    } 
}) 
// returns a plausible number 

をしかし$whereクエリが$pullアップデートで条件として使用することはできません。

db.notes.update({ 
    suggestions: {$exists: true}, 
}, { 
    $pull: { 
     suggestions: { 
      $where: function() { 
       return !!this.suggestions.filter(function (item) { 
        return (item || "").length > 1000; 
       }).length 
      } 
     } 
    } 
}) 

私はアイデアを実行している

WriteResult({ 
    "nMatched" : 0, 
    "nUpserted" : 0, 
    "nModified" : 0, 
    "writeError" : { 
     "code" : 81, 
     "errmsg" : "no context for parsing $where" 
    } 
}) 

をスローします。コレクション全体を繰り返し処理する必要がありますか?$set: {suggestions: suggestions.filter(...)}を各ドキュメントごとに個別に処理しますか? MongoDBの大きな文字列の配列から不正な値を消去する良い方法はありませんか?簡単な解決策が働いている必要があります質問のコメントで指摘

+0

アレイからいくつの要素を削除する必要がありますか? – styvane

+0

各アレイから20未満。通常は、1。 –

+2

また、 'db.notes.count({suggestions:/ \/\ //})'は文字列の長さにかかわらず '/'で文書の数を返すべきです。大きな文字列の場合は、 'updateOne()'メソッドのfilter引数を使用するべきです: 'db.notes.updateOne({suggestions:/ \/\ //}、{" $ pull ":{suggestions:/ \/\ /}}) ' – styvane

答えて

0

(私はSOコードを正しくフォーマットするために取得するために、「ジャバスクリプト」タグを追加している)

。元の問題を再現したテストケースで動作します。正規表現は大きな文字列にマッチすることができますが、特別な制限はありません。

db.notes.updateOne({suggestions: /\/\//}, { "$pull": {suggestions: /\/\//}}) 

これが私のために動作しませんでしたので、私は質問が議論するものと一緒に行くことになった:文字列の長さに基づいて、配列の要素をフィルタリングすることにより、個別にすべてのドキュメントを更新:

db.notes.find({ 
    suggestions: {$exists: true} 
}).forEach(function(doc) { 
    doc.suggestions = doc.suggestions.filter(function(item) { 
     return (item || "").length <= 1000; 
    }); db.notes.save(doc); 
}); 

それは遅い走りましたこれは実際には問題ではありませんでした。

関連する問題