次のようなランダムな種類の区切り文字が使用されている電話番号のフィールドがあります。
932-555-1515
951.555.1255
(952) 555-1414
すでに存在する各フィールドを調べて、数字以外の文字を削除したいと思います。
それは可能ですか?
整数として格納されるか、数値の文字列として格納されるかどうかに関係なく、どちらの方法でもかまいません。表示目的でのみ使用されます。
コード内のすべてのドキュメントを繰り返し処理し、正規表現置換を使用して文字列をクリーンアップする必要があります。
クリーンアップする必要test
のあるフィールドを持つコレクションのmongoシェルでこれを行う方法は次のとおりです。phone
db.test.find().forEach(function(doc) {
doc.phone = doc.phone.replace(/[^0-9]/g, '');
db.test.save(doc);
});
@JohnnyHKによる前の例に基づいて、検索クエリにも正規表現を追加しました。
/*
MongoDB: Find by regular expression and run regex replace on results
*/
db.test.find({"url": { $regex: 'http:\/\/' }}).forEach(function(doc) {
doc.url = doc.url.replace(/http:\/\/www\.url\.com/g, 'http://another.url.com');
db.test.save(doc);
});
からMongo 4.4
、$function
集約演算子を使用すると、カスタムjavascript関数を適用して、MongoDBクエリ言語でサポートされていない動作を実装できます。
db.collection.update()
そして、それに加えられた改善と相まってMongo 4.2
、集約パイプラインを受け入れることができ、それ自体の値に基づいてフィールドを更新できるようになります。
言語が簡単に許可しない方法でフィールドを操作および更新し、非効率的なfind/foreachパターンを回避できます。
// { "x" : "932-555-1515", "y" : 3 }
// { "x" : "951.555.1255", "y" : 7 }
// { "x" : "(952) 555-1414", "y" : 6 }
db.collection.updateMany(
{ "x": { $regex: /[^0-9]/g } },
[{ $set:
{ "x":
{ $function: {
body: function(x) { return x.replace(/[^0-9]/g, ''); },
args: ["$x"],
lang: "js"
}}
}
}
])
// { "x" : "9325551515", "y" : 3 }
// { "x" : "9515551255", "y" : 7 }
// { "x" : "9525551414", "y" : 6 }
アップデートの内容は次のとおりです。
一致クエリ{ "x": { $regex: /[^0-9]/g } }
、更新するドキュメントのフィルタリング(この場合、更新したいフィールドに数字以外の文字を含むドキュメント)。
更新アグリゲーションパイプライン[ { $set: { active: { $eq: [ "$a", "Hello" ] } } } ]
(アグリゲーションパイプラインの使用を示す角かっこに注意してください)。$set
は新しい集計演算子であり、のエイリアスです$addFields
。
$function
3つのパラメータを取ります:
body
、これは適用する関数であり、そのパラメーターは変更する文字列です。ここでの機能は、正規表現に一致する文字を空の文字に置き換えることだけです。args
、body
関数がパラメータとして受け取るレコードのフィールドが含まれています。私たちの場合、"$x"
。lang
、body
関数が記述されている言語です。現在のみjs
ご利用いただけます。mongodbバージョン4.2には、クライアント内のすべてのドキュメントをループすることなく、集計内でsubstrと一緒に使用できるregexFindプロジェクトオペレーターがあります。