[MONGODB] MongoDB를 맵리 듀스에서 어떻게 값 개체를 평평하게 할 수 있습니까?
MONGODBMongoDB를 맵리 듀스에서 어떻게 값 개체를 평평하게 할 수 있습니까?
아파치 로그 파일을 분석하여 MongoDB를 사용하는 것을 시도하고있다. 나는 아파치 액세스 로그에서 영수증 수집을 만들었습니다. 여기 내 모델 모양을의 요약 된 요약이다 :
db.receipts.findOne()
{
"_id" : ObjectId("4e57908c7a044a30dc03a888"),
"path" : "/videos/1/show_invisibles.m4v",
"issued_at" : ISODate("2011-04-08T00:00:00Z"),
"status" : "200"
}
나는 맵리 듀스 기능을 작성한 그룹 그 issued_at 날짜 필드의 모든 데이터입니다. 이 요청의 총 수를 요약하고 각각의 고유 한 경로에 대한 요청의 수의 고장을 제공합니다. 여기에 출력 외모가 좋아의 예입니다 :
db.daily_hits_by_path.findOne()
{
"_id" : ISODate("2011-04-08T00:00:00Z"),
"value" : {
"count" : 6,
"paths" : {
"/videos/1/show_invisibles.m4v" : {
"count" : 2
},
"/videos/1/show_invisibles.ogv" : {
"count" : 3
},
"/videos/6/buffers_listed_and_hidden.ogv" : {
"count" : 1
}
}
}
}
어떻게이 대신 같은 출력 모양을 만들 수 있습니다 :
{
"_id" : ISODate("2011-04-08T00:00:00Z"),
"count" : 6,
"paths" : {
"/videos/1/show_invisibles.m4v" : {
"count" : 2
},
"/videos/1/show_invisibles.ogv" : {
"count" : 3
},
"/videos/6/buffers_listed_and_hidden.ogv" : {
"count" : 1
}
}
}
해결법
-
==============================
1.그것은 현재 불가능하지만이 사건에 대한 투표를 제안했다 : https://jira.mongodb.org/browse/SERVER-2517.
그것은 현재 불가능하지만이 사건에 대한 투표를 제안했다 : https://jira.mongodb.org/browse/SERVER-2517.
-
==============================
2.이전 답변과 의견에서 최고의 촬영 :
이전 답변과 의견에서 최고의 촬영 :
db.items.find().hint({_id: 1}).forEach(function(item) { db.items.update({_id: item._id}, item.value); });
http://docs.mongodb.org/manual/core/update/#replace-existing-document-with-new-document에서 "업데이트 인수는 필드 및 값 쌍 업데이트를 () 메소드는 _id 필드를 제외하고, 업데이트 인수 문서와 기존 문서를 대체합니다.이 포함 된 경우"
당신은 $ 설정되지 않은 값을 둘 필요가 없습니다 그래서 없으며, 각 필드를 나열합니다.
https://docs.mongodb.com/manual/core/read-isolation-consistency-recency/#cursor-snapshot에서 "MongoDB의 커서는 어떤 상황에서 한 번 이상 동일한 문서를 반환 할 수 있습니다. ...이 분야에 고유 인덱스 정도 쿼리를 두 번 이상 각 문서 더 이상 반환하지 것입니다. 쿼리 힌트 () 명시 적으로 강제하기 위해이 필드를 사용 쿼리는 해당 인덱스를 사용합니다. "
-
==============================
3.AFAIK는 디자인 몽고의지도에 의해 "값 튜플"에 결과를 뱉어 줄이고 그 "출력 형식"을 구성합니다 아무것도 보지 못했다. 아마 마무리 () 메소드를 사용할 수 있습니다.
AFAIK는 디자인 몽고의지도에 의해 "값 튜플"에 결과를 뱉어 줄이고 그 "출력 형식"을 구성합니다 아무것도 보지 못했다. 아마 마무리 () 메소드를 사용할 수 있습니다.
당신은 사용하여 데이터를 재 형성하는 후 공정을 실행하려고 할 수
results.find({}).forEach( function(result) { results.update({_id: result._id}, {count: result.value.count, paths: result.value.paths}) });
그래, 그 추한 보인다. 알아.
-
==============================
4.당신은 수집 참조 댄의 코드를 수행 할 수 있습니다
당신은 수집 참조 댄의 코드를 수행 할 수 있습니다
function clean(collection) { collection.find().forEach( function(result) { var value = result.value; delete value._id; collection.update({_id: result._id}, value); collection.update({_id: result.id}, {$unset: {value: 1}} ) } )};
-
==============================
5.@ljonas의 그것과 유사한 접근하지만 하드 코드 문서 필드에 대한 필요가 없습니다 :
@ljonas의 그것과 유사한 접근하지만 하드 코드 문서 필드에 대한 필요가 없습니다 :
db.results.find().forEach( function(result) { var value = result.value; delete value._id; db.results.update({_id: result._id}, value); db.results.update({_id: result.id}, {$unset: {value: 1}} ) } );
-
==============================
6.모든 제안 된 솔루션은 최적의 거리가 멀다. 지금까지 할 수있는 가장 빠른 같은 것입니다 :
모든 제안 된 솔루션은 최적의 거리가 멀다. 지금까지 할 수있는 가장 빠른 같은 것입니다 :
var flattenMRCollection=function(dbName,collectionName) { var collection=db.getSiblingDB(dbName)[collectionName]; var i=0; var bulk=collection.initializeUnorderedBulkOp(); collection.find({ value: { $exists: true } }).addOption(16).forEach(function(result) { print((++i)); //collection.update({_id: result._id},result.value); bulk.find({_id: result._id}).replaceOne(result.value); if(i%1000==0) { print("Executing bulk..."); bulk.execute(); bulk=collection.initializeUnorderedBulkOp(); } }); bulk.execute(); };
그런 다음 전화 : flattenMRCollection ( "보기 MyDB", "MyMRCollection")
이것은 빠른 연속 업데이트를하는 것보다 길이다.
-
==============================
7.빈센트의 대답을 실험하는 동안, 나는 몇 가지 문제를 발견했다. 당신이 foreach 루프 내에서 업데이트를 수행하는 경우 기본적으로,이 컬렉션의 끝에 문서를 이동하고 커서는 다시 문서 (예)에 도달 할 것이다. $ 스냅 샷을 사용하는 경우는 피할 수있다. 따라서, 나는 아래 자바 예제를 제공하고 있습니다.
빈센트의 대답을 실험하는 동안, 나는 몇 가지 문제를 발견했다. 당신이 foreach 루프 내에서 업데이트를 수행하는 경우 기본적으로,이 컬렉션의 끝에 문서를 이동하고 커서는 다시 문서 (예)에 도달 할 것이다. $ 스냅 샷을 사용하는 경우는 피할 수있다. 따라서, 나는 아래 자바 예제를 제공하고 있습니다.
final List<WriteModel<Document>> bulkUpdate = new ArrayList<>(); // You should enable $snapshot if performing updates within foreach collection.find(new Document().append("$query", new Document()).append("$snapshot", true)).forEach(new Block<Document>() { @Override public void apply(final Document document) { // Note that I used incrementing long values for '_id'. Change to String if // you used string '_id's long docId = document.getLong("_id"); Document subDoc = (Document)document.get("value"); WriteModel<Document> m = new ReplaceOneModel<>(new Document().append("_id", docId), subDoc); bulkUpdate.add(m); // If you used non-incrementing '_id's, then you need to use a final object with a counter. if(docId % 1000 == 0 && !bulkUpdate.isEmpty()) { collection.bulkWrite(bulkUpdate); bulkUpdate.removeAll(bulkUpdate); } } }); // Fixing bug related to Vincent's answer. if(!bulkUpdate.isEmpty()) { collection.bulkWrite(bulkUpdate); bulkUpdate.removeAll(bulkUpdate); }
참고 :이 조각은 100,000 기록, 14 개 특성 (IMDB 데이터 세트) 내 컴퓨터에서 실행하는 데 7.4 초 평균 소요됩니다. 일괄 없이는 25.2 초 평균 소요됩니다.
from https://stackoverflow.com/questions/7257989/in-mongodb-mapreduce-how-can-i-flatten-the-values-object by cc-by-sa and MIT license
'MONGODB' 카테고리의 다른 글
[MONGODB] ObjectId가가 몽구스를 사용하여 검색하는 문서를 찾을 수 없습니다 (0) | 2019.12.22 |
---|---|
[MONGODB] MongoDB를 C #을 드라이버 - 바인딩에 필드를 무시 (0) | 2019.12.22 |
[MONGODB] 어떻게 몽구스 모델의 메소드를 정의합니까? (0) | 2019.12.22 |
[MONGODB] 몽고없이 유성 (0) | 2019.12.22 |
[MONGODB] MongoDB의 연결을 처리하는 올바른 방법은 무엇입니까? (0) | 2019.12.22 |