[MONGODB] 컬렉션의 속성을 매핑하기위한 감소 /지도 사용
MONGODB컬렉션의 속성을 매핑하기위한 감소 /지도 사용
업데이트 : 후속 MongoDB를에이 컬렉션의 모든 키의 이름을 가져옵니다.
크리스티나가 지적한 바와 같이, 하나는 컬렉션의 키를 나열 감소 / MongoDB를의지도를 사용할 수 있습니다 :
db.things.insert( { type : ['dog', 'cat'] } );
db.things.insert( { egg : ['cat'] } );
db.things.insert( { type : [] });
db.things.insert( { hello : [] } );
mr = db.runCommand({"mapreduce" : "things",
"map" : function() {
for (var key in this) { emit(key, null); }
},
"reduce" : function(key, stuff) {
return null;
}})
db[mr.result].distinct("_id")
//output: [ "_id", "egg", "hello", "type" ]
만큼 우리가 깊이의 첫 번째 수준에있는 유일한 열쇠를 얻으려면,이 잘 작동합니다. 그러나 더 깊은 수준에있는 그 열쇠를 검색 실패합니다. 우리는 새 레코드를 추가하는 경우 :
db.things.insert({foo: {bar: {baaar: true}}})
그리고 우리가 위에서 + 별개의 조각지도가-줄이기 다시 실행, 우리는 얻을 것이다 :
[ "_id", "egg", "foo", "hello", "type" ]
그러나 우리는 데이터 구조에서 아래로 중첩 된 바와 baaar 키를 얻을 수 없습니다. 질문 : 어떻게 내가 모든 키를 검색 깊이에 상관없이 자신의 수준을합니까? 이상적으로, 사실은 스크립트와 같은 출력을 같은 생산, 깊이의 모든 수준에 걸어 것입니다 :
["_id","egg","foo","foo.bar","foo.bar.baaar","hello","type"]
사전에 감사합니다!
해결법
-
==============================
1.OK, 이것은 좀 더 복잡한 일부 재귀를 사용해야하기 때문이다.
OK, 이것은 좀 더 복잡한 일부 재귀를 사용해야하기 때문이다.
재귀 일어날 수 있도록하려면 서버에 일부 기능을 저장할 수해야합니다.
isArray = function (v) { return v && typeof v === 'object' && typeof v.length === 'number' && !(v.propertyIsEnumerable('length')); } m_sub = function(base, value){ for(var key in value) { emit(base + "." + key, null); if( isArray(value[key]) || typeof value[key] == 'object'){ m_sub(base + "." + key, value[key]); } } } db.system.js.save( { _id : "isArray", value : isArray } ); db.system.js.save( { _id : "m_sub", value : m_sub } );
map = function(){ for(var key in this) { emit(key, null); if( isArray(this[key]) || typeof this[key] == 'object'){ m_sub(key, this[key]); } } } reduce = function(key, stuff){ return null; }
mr = db.runCommand({"mapreduce" : "things", "map" : map, "reduce" : reduce,"out": "things" + "_keys"}); db[mr.result].distinct("_id");
당신이 얻을 것이다 결과는 다음과 같습니다
["_id", "_id.isObjectId", "_id.str", "_id.tojson", "egg", "egg.0", "foo", "foo.bar", "foo.bar.baaaar", "hello", "type", "type.0", "type.1"]
하나의 명백한 문제는 우리가 여기에 몇 가지 예상치 못한 필드를 추가하고, 여기에 있습니다 : 1. 데이터 _id 2. 0.0 (계란과 유형에 대한)
문제 # 1에 대한 수정은 상대적으로 쉽다. 그냥지도 기능을 수정합니다. 이 변경 :
emit(base + "." + key, null); if( isArray...
이에:
if(key != "_id") { emit(base + "." + key, null); if( isArray... }
문제 # 2는 좀 더 아슬 아슬하다. 당신은 모든 키를 원하고 기술적으로 "egg.0는"유효한 키입니다. 당신은 숫자 키를 무시 m_sub을 수정할 수 있습니다. 그러나이 곳 역화 상황을 볼 수도 쉽다. 그런 다음 당신이이 "0"으로 표시 할, 규칙적인 배열의 연관 배열의 내부를 말해봐. 나는 당신에게 해당 솔루션의 최대의 나머지 부분을 떠날거야.
-
==============================
2.https://github.com/variety/variety : 게이츠 부사장의 영감으로 크리스티나의 응답으로, 나는 정확히 수행 다양한라는 오픈 소스 도구를 개발
https://github.com/variety/variety : 게이츠 부사장의 영감으로 크리스티나의 응답으로, 나는 정확히 수행 다양한라는 오픈 소스 도구를 개발
희망 당신은 도움이 될 그것을 찾을 수 있습니다. 질문, 또는를 사용하여 문제가있을 경우 알려주세요.
-
==============================
3.간단한 함수로서;
간단한 함수로서;
const getProps = (db, collection) => new Promise((resolve, reject) => { db .collection(collection) .mapReduce(function() { for (var key in this) { emit(key, null) } }, (prev, next) => null, { out: collection + '_keys' }, (err, collection_props) => { if (err) reject(err) collection_props .find() .toArray() .then( props => resolve(props.map(({_id}) => _id)) ) }) })
from https://stackoverflow.com/questions/2997004/using-map-reduce-for-mapping-the-properties-in-a-collection by cc-by-sa and MIT license
'MONGODB' 카테고리의 다른 글
[MONGODB] 어레이 내 요소 MongoDB에 의해 기 (0) | 2019.12.04 |
---|---|
[MONGODB] 하지 덮어 쓰기 모델은 한 번 몽구스를 컴파일 할 수 (0) | 2019.12.04 |
[MONGODB] MongoDB의에서 중첩 된 배열을 업데이트 (0) | 2019.12.04 |
[MONGODB] 기존의 모든 필드를 포함하고 문서에 새로운 필드를 추가 (0) | 2019.12.04 |
[MONGODB] MongoDB를 집계 방법 : 총 기록을 계산 얻을? (0) | 2019.12.04 |