[MONGODB] $ 조회 후 집계 필터
MONGODB$ 조회 후 집계 필터
어떻게 $ 조회 후 필터를 추가하거나이 작업을 수행하는 다른 방법이있다 할 수 있습니까?
내 데이터 수집 시험은 다음과 같습니다
{ "_id" : ObjectId("570557d4094a4514fc1291d6"), "id" : 100, "value" : "0", "contain" : [ ] }
{ "_id" : ObjectId("570557d4094a4514fc1291d7"), "id" : 110, "value" : "1", "contain" : [ 100 ] }
{ "_id" : ObjectId("570557d4094a4514fc1291d8"), "id" : 120, "value" : "1", "contain" : [ 100 ] }
{ "_id" : ObjectId("570557d4094a4514fc1291d9"), "id" : 121, "value" : "2", "contain" : [ 100, 120 ] }
나는 ID 100을 선택하고 차일 집계 :
db.test.aggregate([ {
$match : {
id: 100
}
}, {
$lookup : {
from : "test",
localField : "id",
foreignField : "contain",
as : "childs"
}
}]);
난 돌아가 겠어:
{
"_id":ObjectId("570557d4094a4514fc1291d6"),
"id":100,
"value":"0",
"contain":[ ],
"childs":[ {
"_id":ObjectId("570557d4094a4514fc1291d7"),
"id":110,
"value":"1",
"contain":[ 100 ]
},
{
"_id":ObjectId("570557d4094a4514fc1291d8"),
"id":120,
"value":"1",
"contain":[ 100 ]
},
{
"_id":ObjectId("570557d4094a4514fc1291d9"),
"id":121,
"value":"2",
"contain":[ 100, 120 ]
}
]
}
하지만 난 단지와 일치하는 차일 싶다 "값 : 1"
마지막에 나는이 결과를 기대합니다 :
{
"_id":ObjectId("570557d4094a4514fc1291d6"),
"id":100,
"value":"0",
"contain":[ ],
"childs":[ {
"_id":ObjectId("570557d4094a4514fc1291d7"),
"id":110,
"value":"1",
"contain":[ 100 ]
},
{
"_id":ObjectId("570557d4094a4514fc1291d8"),
"id":120,
"value":"1",
"contain":[ 100 ]
}
]
}
해결법
-
==============================
1.여기에서 문제는 뭔가 다른에 대해 사실과 전혀 조회 $ 필요하지 않습니다. 그러나 누구든지 다음 "$ 조회 한 후 필터링"의 제목에서 순전히 여기 도착 이러한 당신을위한 방법은 다음과 같습니다 :
여기에서 문제는 뭔가 다른에 대해 사실과 전혀 조회 $ 필요하지 않습니다. 그러나 누구든지 다음 "$ 조회 한 후 필터링"의 제목에서 순전히 여기 도착 이러한 당신을위한 방법은 다음과 같습니다 :
db.test.aggregate([ { "$match": { "id": 100 } }, { "$lookup": { "from": "test", "let": { "id": "$id" }, "pipeline": [ { "$match": { "value": "1", "$expr": { "$in": [ "$$id", "$contain" ] } }} ], "as": "childs" }} ])
db.test.aggregate([ { "$match": { "id": 100 } }, { "$lookup": { "from": "test", "localField": "id", "foreignField": "contain", "as": "childs" }}, { "$unwind": "$childs" }, { "$match": { "childs.value": "1" } }, { "$group": { "_id": "$_id", "id": { "$first": "$id" }, "value": { "$first": "$value" }, "contain": { "$first": "$contain" }, "childs": { "$push": "$childs" } }} ])
배열에 $ 필터를 사용하여 반대로 것 당신은 언 와인드 $ 이유를 질문하면, 파이프 라인이 일반적으로 필요한 이유에 모든 세부 사항에 대한 최대 문서 크기를 초과 일치에 문서와 훨씬 더 최적의 집계 $ 조회 총 크기를 참조하십시오.
MongoDB를 3.6 릴리스 및 이후, 다음 더 표현 "하위 파이프 라인은"아무것도 전혀 배열에 반환되기 전에 당신이 외국 모음의 "필터"결과에 원하는 일반적이다.
위로 대답하는하지만 실제로 .... 문제는 요구를 물었다 전혀 "더 가입"을 설명하지
이 같은 $ 조회를 사용하면 여기에 원하는 것을 할 수있는 가장 "효율적인"방법이 아니다. 하지만 더이에 이상이 필요합니다.
기본 개념으로, 단지 결과 배열에 $ 필터를 사용 :
db.test.aggregate([ { "$match": { "id": 100 } }, { "$lookup": { "from": "test", "localField": "id", "foreignField": "contain", "as": "childs" }}, { "$project": { "id": 1, "value": 1, "contain": 1, "childs": { "$filter": { "input": "$childs", "as": "child", "cond": { "$eq": [ "$$child.value", "1" ] } } } }} ]);
또는 $ 편집하다을 대신 사용
db.test.aggregate([ { "$match": { "id": 100 } }, { "$lookup": { "from": "test", "localField": "id", "foreignField": "contain", "as": "childs" }}, { "$redact": { "$cond": { "if": { "$or": [ { "$eq": [ "$value", "0" ] }, { "$eq": [ "$value", "1" ] } ] }, "then": "$$DESCEND", "else": "$$PRUNE" } }} ]);
모두 같은 결과를 얻을 :
{ "_id":ObjectId("570557d4094a4514fc1291d6"), "id":100, "value":"0", "contain":[ ], "childs":[ { "_id":ObjectId("570557d4094a4514fc1291d7"), "id":110, "value":"1", "contain":[ 100 ] }, { "_id":ObjectId("570557d4094a4514fc1291d8"), "id":120, "value":"1", "contain":[ 100 ] } ] }
결론은 특정 데이터를 선택에 $ 쿼리 자체를 할 수없는 조회 "아직"이다. 모든 "필터링"요구는 $ 조회 후 발생하는 그래서
하지만 실제로는 "자체 가입"이러한 유형의 당신은 더 나은 오프 모두에서 $ 조회를 사용하고 추가로 읽기와 완전히 "해시 병합 '의 오버 헤드를 피할 수 없습니다. 그냥 관련 항목 대신 $ 그룹을 가져 오기 :
db.test.aggregate([ { "$match": { "$or": [ { "id": 100 }, { "contain.0": 100, "value": "1" } ] }}, { "$group": { "_id": { "$cond": { "if": { "$eq": [ "$value", "0" ] }, "then": "$id", "else": { "$arrayElemAt": [ "$contain", 0 ] } } }, "value": { "$first": { "$literal": "0"} }, "childs": { "$push": { "$cond": { "if": { "$ne": [ "$value", "0" ] }, "then": "$$ROOT", "else": null } } } }}, { "$project": { "value": 1, "childs": { "$filter": { "input": "$childs", "as": "child", "cond": { "$ne": [ "$$child", null ] } } } }} ])
어느 내가 의도적으로 외부 필드를 제거하기 때문에 조금 밖에 다른 나옵니다. 당신이 정말로 원하는 경우 자신에 추가 :
{ "_id" : 100, "value" : "0", "childs" : [ { "_id" : ObjectId("570557d4094a4514fc1291d7"), "id" : 110, "value" : "1", "contain" : [ 100 ] }, { "_id" : ObjectId("570557d4094a4514fc1291d8"), "id" : 120, "value" : "1", "contain" : [ 100 ] } ] }
유일한 진짜 문제는 여기에있다 그래서 현재 문서는 $ 푸시 항목을 처리 할 때 부모가되었을 때 생성 된 배열에서 모든 널 (null) 결과를 "필터링".
당신이 여기없는 것 같다 당신이 찾고있는 결과가 필요 집계 또는 전부에서 "하위 쿼리를"하지 않습니다. 당신이 가능하게 체결 또는 것을 구조는 그래서 당신은 하나의 질의 요청에 "노드"과의 "아이들"을 모두 얻을 수 있습니다 "설계"되어 다른 곳에서 찾을.
수단 단지 "쿼리는"커서 결과를 반복 단지 기능 (어떤 내용이 정말 "감소하지"되고 이후 일어나는 모든입니다) 정말 필요한 모든 및 데이터 수집을한다 즉 :
var result = {}; db.test.find({ "$or": [ { "id": 100 }, { "contain.0": 100, "value": "1" } ] }).sort({ "contain.0": 1 }).forEach(function(doc) { if ( doc.id == 100 ) { result = doc; result.childs = [] } else { result.childs.push(doc) } }) printjson(result);
이것은 정확히 같은 일을한다 :
{ "_id" : ObjectId("570557d4094a4514fc1291d6"), "id" : 100, "value" : "0", "contain" : [ ], "childs" : [ { "_id" : ObjectId("570557d4094a4514fc1291d7"), "id" : 110, "value" : "1", "contain" : [ 100 ] }, { "_id" : ObjectId("570557d4094a4514fc1291d8"), "id" : 120, "value" : "1", "contain" : [ 100 ] } ] }
그리고 당신이 정말로 여기해야 할 모든 문제는 부모와 자녀 모두를 선택할 수있는 "싱글"쿼리는 증거 역할을한다. 반환 된 데이터는 동일합니다, 당신이 중 하나를 서버 또는 클라이언트에서 수행되는 모든 다른 수집 된 형식으로 "마사지"입니다.
사용이 당신이 당신이 "관계형"데이터베이스에 일을 어떻게했는지 생각에 "잡았다"얻을 수있는 이러한 경우 중 하나이며, 데이터가 저장되는 방식이 "변화"이후 그 실현하지, 더 이상 필요 같은 접근 방식.
그게 정확히 무엇인지는 쉽게 하나 개의 쿼리 내에서 부모와 자녀를 선택하게 그것의 구조에서 "하위 참조와 모델 트리 구조"문서 예제의 포인트입니다.
from https://stackoverflow.com/questions/36459983/aggregation-filter-after-lookup by cc-by-sa and MIT license
'MONGODB' 카테고리의 다른 글
[MONGODB] MongoDB의 날짜를 문자열로 변환 (0) | 2019.12.01 |
---|---|
[MONGODB] 정수 값에 MongoDB를 정규식 검색 (0) | 2019.12.01 |
[MONGODB] MongoDB를 업데이트 깊이 하위 문서를 중첩 (0) | 2019.12.01 |
[MONGODB] Mongod은 / 데이터 / DB 폴더가 더 있다는 것을 불평하지 (0) | 2019.12.01 |
[MONGODB] 복수는 $ 검색 연산자를 사용하여 조인 조건 (0) | 2019.12.01 |