2016-04-04 7 views
0

Ve eski çizgi kaçan böcek böylece gibi bazı berbat verilerle bize bıraktı:

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

Sadece dizinin dışına o kötü değerler getirilmesini istiyoruz. Benim ilk fikir 4 "/" ​​karakterlerini eşleşen bir regex dayalı $pull oldu ama regexes büyük dizeleri çalışmaz için görünür:

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

Benim sonraki fikri belgeleri bulmak için bir $where sorgu kullanmak olduğuna Bu sorgu çalışır uzun 1000'den daha vardır suggestion dizeleri vardır:

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

Ama $where sorgu $pull güncellemesinde koşulu olarak kullanılamaz.

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

fikirlerim tükeniyor

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

atar. Her bir koleksiyon için tek tek ve her bir belge için $set: {suggestions: suggestions.filter(...)}'u tekrarlamak zorunda mıyım? MongoDB'deki büyük dizelerden oluşan kötü değerleri temizlemenin daha iyi bir yolu yok mu? basit bir çözüm çalışmış gereken soru Açıklamalarda belirttiği

+0

Diziden kaldırmak için kaç öğe gerekir? – styvane

+0

Her diziden 20'den az. Genellikle 1. –

+2

Ayrıca 'db.notes.count ({öneriler:/\/\ //})' dizininizin uzunluğu ne olursa olsun '/' ile belgelerin sayısını döndürmelidir. Büyük dize için söylenen bu filtre argümanını 'updateOne()' metoduna kullanmalısınız: 'db.notes.updateOne ({öneriler:/\/\ //}, {" $ pull ": {öneriler:/\/\ //}}) – styvane

cevap

0

(sadece SO kodu doğru biçimlendirmek için elde etmek için "javascript" etiketi ekleyerek ediyorum)

. Orijinal problemin rekreasyonu olan bir test çalışması ile çalışır. Regexler geniş dizelerle eşleşebilir, orada özel bir kısıtlama yoktur. Bu yana

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

benim için işe yaramadı, ben soru tartışılan ne gidiş sona erdi: Bu yavaş koştu

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

: string uzunluğuna dayalı dizi elemanlarını filtreleyerek ayrı ayrı tüm dokümanları güncellenmesi ama bu durumda gerçekten bir sorun değildi.

İlgili konular