Mongo의 모든 문서에서 문자열을 바꾸는 방법
특정 문서의 문자열을 교체해야 합니다.이 코드를 구글에 검색했지만 아쉽게도 변경되지 않았습니다.아래 행의 구문에 대해 잘 모르겠습니다.
pulpdb = db.getSisterDB("pulp_database");
var cursor = pulpdb.repos.find();
while (cursor.hasNext()) {
var x = cursor.next();
x['source']['url'].replace('aaa', 'bbb'); // is this correct?
db.foo.update({_id : x._id}, x);
}
값이 얼마인지 보기 위해 디버그 프린트를 추가하고 싶지만 MongoDB Shell에 대한 경험이 없습니다.이것만 교체하면 됩니다.
{ "source": { "url": "http://aaa/xxx/yyy" } }
와 함께
{ "source": { "url": "http://bbb/xxx/yyy" } }
일반적으로 수정되지 않습니다. 문자열이 있는 경우http://aaa/xxx/aaa
(yyy
와 동등한.aaa
)로 끝나게 될 것입니다.http://bbb/xxx/bbb
하지만 당신이 이것에 동의한다면, 코드는 작동할 것입니다.
디버그 정보를 추가하려면 사용print
함수:
var cursor = db.test.find();
while (cursor.hasNext()) {
var x = cursor.next();
print("Before: "+x['source']['url']);
x['source']['url'] = x['source']['url'].replace('aaa', 'bbb');
print("After: "+x['source']['url']);
db.test.update({_id : x._id}, x);
}
(그런데, 만약 당신이 물건을 인쇄하고 싶다면, 또한 있습니다.printjson
함수)
MongoDB 2.6 이상 버전에 있는 경우 가장 좋은 방법은 메서드를 사용하여 커서 오브젝트를 루프하고 "대량" 작업으로 각 문서를 업데이트하여 효율성을 극대화하는 것입니다.
var bulk = db.collection.initializeOrderedBulkOp();
var count = 0;
db.collection.find().forEach(function(doc) {
print("Before: "+doc.source.url);
bulk.find({ '_id': doc._id }).update({
'$set': { 'source.url': doc.source.url.replace('aaa', 'bbb') }
})
count++;
if(count % 200 === 0) {
bulk.execute();
bulk = db.collection.initializeOrderedBulkOp();
}
// Clean up queues
if (count > 0)
bulk.execute();
MongoDB 3.2부터는 Bulk() API 및 관련 메서드가 더 이상 사용되지 않습니다. 이 메서드를 사용해야 합니다.
커서를 루프하여 쿼리를 동적으로 빌드하고 각 작업을 배열로 만들어야 합니다.
var operations = [];
db.collection.find().forEach(function(doc) {
print("Before: "+doc.source.url);
var operation = {
updateOne: {
filter: { '_id': doc._id },
update: {
'$set': { 'source.url': doc.source.url.replace('aaa', 'bbb') }
}
}
};
operations.push(operation);
})
operations.push({
ordered: true,
writeConcern: { w: "majority", wtimeout: 5000 }
})
db.collection.bulkWrite(operations);
요즘 들어,
- 시작하는
Mongo 4.2
(db.collection.updateMany
대신)db.collection.update
)에서 집계 파이프라인을 허용할 수 있으며, 마지막으로 자체 값을 기준으로 필드를 업데이트할 수 있습니다. - 시작하는
Mongo 4.4
새로운 집계 연산자를 사용하면 문자열의 일부를 매우 쉽게 바꿀 수 있습니다.
// { "source" : { "url" : "http://aaa/xxx/yyy" } }
// { "source" : { "url" : "http://eee/xxx/yyy" } }
db.collection.updateMany(
{ "source.url": { $regex: /aaa/ } },
[{
$set: { "source.url": {
$replaceOne: { input: "$source.url", find: "aaa", replacement: "bbb" }
}}
}]
)
// { "source" : { "url" : "http://bbb/xxx/yyy" } }
// { "source" : { "url" : "http://eee/xxx/yyy" } }
- 첫 번째 부분 (
{ "source.url": { $regex: /aaa/ } }
)는 업데이트할 문서(다음을 포함하는 문서)를 필터링하는 일치 쿼리입니다."aaa"
) - 두 번째 부분(
$set: { "source.url": {...
)는 업데이트 집계 파이프라인입니다(집계 파이프라인 사용을 나타내는 대괄호 참조).$set
는 새로운 집계 연산자(Mongo 4.2
이 경우 필드 값을 대체합니다.- 새 값은 새 연산자를 사용하여 계산됩니다.방법에 주목
source.url
자체 값을 기준으로 직접 수정됩니다($source.url
).
이것은 질문의 디버그 인쇄 부분을 수행할 수 없는 완전히 처리된 서버 측입니다.
MongoDB는 맵리듀스를 통해 문자열 검색/교체를 수행할 수 있습니다.예, 이를 위해 매우 특별한 데이터 구조가 필요합니다. 맨 위 키에는 아무것도 있을 수 없지만 모든 것을 하위 문서 아래에 저장해야 합니다.value
다음과 같이:
{
"_id" : ObjectId("549dafb0a0d0ca4ed723e37f"),
"value" : {
"title" : "Top 'access denied' errors",
"parent" : "system.admin_reports",
"p" : "\u0001\u001a%"
}
}
이렇게 깔끔하게 설정되면 다음 작업을 수행할 수 있습니다.
$map = new \MongoCode("function () {
this.value['p'] = this.value['p'].replace('$from', '$to');
emit(this._id, this.value);
}");
$collection = $this->mongoCollection();
// This won't be called.
$reduce = new \MongoCode("function () { }");
$collection_name = $collection->getName();
$collection->db->command([
'mapreduce' => $collection_name,
'map' => $map,
'reduce' => $reduce,
'out' => ['merge' => $collection_name],
'query' => $query,
'sort' => ['_id' => 1],
]);
언급URL : https://stackoverflow.com/questions/10042450/how-to-replace-string-in-all-documents-in-mongo
'programing' 카테고리의 다른 글
MongoDB: 스키마를 어떻게 정의합니까? (0) | 2023.06.24 |
---|---|
C#에서 LIKE를 사용하는 Oracle 바인딩 변수 사용 (0) | 2023.06.24 |
PLSQL JDBC:마지막 행 ID를 가져오는 방법? (0) | 2023.06.19 |
Firebase용 Cloud Functions 오류: "400, 함수 트리거 유형 또는 이벤트 공급자를 변경할 수 없습니다." (0) | 2023.06.19 |
농담 유형 스크립트 - 모의 날짜 생성자 (0) | 2023.06.19 |