[MONGODB] 배열에 ObjectId가의에 조회 $
MONGODB배열에 ObjectId가의에 조회 $
하며 Object의 배열이 하나의 ObjectId가보다는있는 필드에 $ 조회를 수행하는 구문은 무엇입니까?
예 주문 문서 :
{
_id: ObjectId("..."),
products: [
ObjectId("..<Car ObjectId>.."),
ObjectId("..<Bike ObjectId>..")
]
}
작동하지 않음 검색어 :
db.orders.aggregate([
{
$lookup:
{
from: "products",
localField: "products",
foreignField: "_id",
as: "productObjects"
}
}
])
원하는 결과
{
_id: ObjectId("..."),
products: [
ObjectId("..<Car ObjectId>.."),
ObjectId("..<Bike ObjectId>..")
],
productObjects: [
{<Car Object>},
{<Bike Object>}
],
}
해결법
-
==============================
1.은 $ 조회 집계 파이프 라인 단계는 배열을 직접 작동하지 않습니다. A가 가능한 관련 데이터 (또는 정말 "조회") 가입의 "한 많은이"형식으로 "왼쪽 가입"을 위해 디자인의 주요 목적이다. 그러나이 값 배열을 특이 것으로 의도되지 않는다.
은 $ 조회 집계 파이프 라인 단계는 배열을 직접 작동하지 않습니다. A가 가능한 관련 데이터 (또는 정말 "조회") 가입의 "한 많은이"형식으로 "왼쪽 가입"을 위해 디자인의 주요 목적이다. 그러나이 값 배열을 특이 것으로 의도되지 않는다.
그러므로 반드시 먼저 이전 작업이 순서에 $ 조회 작업을 수행하는 "드 정상화"내용. 그리고 수단은 $ 언 와인드를 사용하는 것을 :
db.orders.aggregate([ // Unwind the source { "$unwind": "$products" }, // Do the lookup matching { "$lookup": { "from": "products", "localField": "products", "foreignField": "_id", "as": "productObjects" }}, // Unwind the result arrays ( likely one or none ) { "$unwind": "$productObjects" }, // Group back to arrays { "$group": { "_id": "$_id", "products": { "$push": "$products" }, "productObjects": { "$push": "$productObjects" } }} ])
$ 조회는 각 배열 구성원과 일치 한 후 다시 언 와인드 $ 및 $에서 $ 그룹이 최종 결과를 새로운 배열을 밀어 그래서 결과는, 배열 자체입니다.
어떤 주어진 제품의 "productObjects"에 대한 하늘의 배열을 만듭니다 발견하고, 따라서 두 번째 $의 언 와인드가 호출되는 "제품"요소에 대한 문서를 부정하지 않는 일치 "왼쪽 가입"합니다.
배열에 직접 응용 프로그램이 좋은 것입니다 만, 이것이 현재 가능한 많은에 특이 값을 일치시켜 작동하는 단지 방법입니다.
$ 조회가 기본적으로 아주 새로운, 그것은 현재 .populate () 메소드의 "가난한 망 버전"으로 몽구스 잘 알고있는 사람들에게 친숙한 존재가 제공하는 것처럼 작동합니다. 인 차이 그 처리 $ 조회 이벤트 "서버 측"는 클라이언트에 반대하고 "가입"$ 조회에서 "성숙"의 일부는 현재 () .populate 것과 같은 조회를 보간과 같은 제안을 (부족한 것을 직접)에 배열.
이 때문에 일부 운이 곧 후 다음 릴리스 또는 하나를 명중 것, 실제로 개선 SERVER-22881에 대한 할당 문제입니다.
디자인 원리로서, 현재의 구조가 좋은, 나쁜,하지만 오버 헤드 단지 대상이 하나가 "가입"창조도 아니다. 당신은 데이터를 라이브 한 컬렉션 "사전에 합류", "수"경우에 따라서, 처음에 MongoDB를의 기본 서 원칙을 적용, 그것은 그렇게하는 것이 최선입니다.
원칙적으로 $ 조회라고 할 수있는 하나 개의 다른 점은 여기에 표시된 것보다 여기에 "참여"의 의도가 주변의 다른 방식으로 작동하는 것입니다. "관련 문서"는 "부모"에 대한 참조를 포함 할 경우 그래서 오히려 "부모"문서에 다른 문서의 "관련 ID를"유지하는 것보다, 가장 적합한 일반 원칙이다.
그래서 $ 조회는 몽구스 .populate 같은 () 수행 그것의 클라이언트 측 조인 방법의 역입니다 "관련 디자인"과 "일 최고"라고 할 수 있습니다. 대신 각 "많은"내 "을"idendifying함으로써, 당신은 먼저 배열을 언 와인드 $ 할 필요없이 관련 항목에서 빼냅니다.
-
==============================
2.$ 조회 집계 파이프 라인 단계 지금에 (배열을 직접 작동 3.3.4 버전).
$ 조회 집계 파이프 라인 단계 지금에 (배열을 직접 작동 3.3.4 버전).
참조 : 룩업 값 외국 (인) 값의 로컬 (다중) 어레이 사이
-
==============================
3.또한 하위 배열에 검사를 수행하기 위해 파이프 라인 단계를 사용할 수 있습니다
또한 하위 배열에 검사를 수행하기 위해 파이프 라인 단계를 사용할 수 있습니다
여기에 (미안 해요 뱀 사람이야) 파이썬을 사용하는 예입니다.
db.products.aggregate([ { '$lookup': { 'from': 'products', 'let': { 'pid': '$products' }, 'pipeline': [ { '$match': { '$expr': { '$in': ['$_id', '$$pid'] } } } // Add additional stages here ], 'as':'productObjects' } ])
여기 캐치 ObjectId가 배열 (현지 필드 / 소품 제품에 외국 _id)에있는 모든 개체와 일치하는 것입니다.
또한 청소 또는 위의 주석으로 표시된 바와 같이, 추가 단계로 외국 기록을 투사 할 수 있습니다.
-
==============================
4.대신 객체의 배열의 첫 번째 개체를 얻을 것이다 긴장을 풀고 $를 사용
대신 객체의 배열의 첫 번째 개체를 얻을 것이다 긴장을 풀고 $를 사용
질문:
db.getCollection('vehicles').aggregate([ { $match: { status: "AVAILABLE", vehicleTypeId: { $in: Array.from(newSet(d.vehicleTypeIds)) } } }, { $lookup: { from: "servicelocations", localField: "locationId", foreignField: "serviceLocationId", as: "locations" } }, { $unwind: "$locations" } ]);
결과:
{ "_id" : ObjectId("59c3983a647101ec58ddcf90"), "vehicleId" : "45680", "regionId" : 1.0, "vehicleTypeId" : "10TONBOX", "locationId" : "100", "description" : "Isuzu/2003-10 Ton/Box", "deviceId" : "", "earliestStart" : 36000.0, "latestArrival" : 54000.0, "status" : "AVAILABLE", "accountId" : 1.0, "locations" : { "_id" : ObjectId("59c3afeab7799c90ebb3291f"), "serviceLocationId" : "100", "regionId" : 1.0, "zoneId" : "DXBZONE1", "description" : "Masafi Park Al Quoz", "locationPriority" : 1.0, "accountTypeId" : 0.0, "locationType" : "DEPOT", "location" : { "makani" : "", "lat" : 25.123091, "lng" : 55.21082 }, "deliveryDays" : "MTWRFSU", "timeWindow" : { "timeWindowTypeId" : "1" }, "address1" : "", "address2" : "", "phone" : "", "city" : "", "county" : "", "state" : "", "country" : "", "zipcode" : "", "imageUrl" : "", "contact" : { "name" : "", "email" : "" }, "status" : "", "createdBy" : "", "updatedBy" : "", "updateDate" : "", "accountId" : 1.0, "serviceTimeTypeId" : "1" } } { "_id" : ObjectId("59c3983a647101ec58ddcf91"), "vehicleId" : "81765", "regionId" : 1.0, "vehicleTypeId" : "10TONBOX", "locationId" : "100", "description" : "Hino/2004-10 Ton/Box", "deviceId" : "", "earliestStart" : 36000.0, "latestArrival" : 54000.0, "status" : "AVAILABLE", "accountId" : 1.0, "locations" : { "_id" : ObjectId("59c3afeab7799c90ebb3291f"), "serviceLocationId" : "100", "regionId" : 1.0, "zoneId" : "DXBZONE1", "description" : "Masafi Park Al Quoz", "locationPriority" : 1.0, "accountTypeId" : 0.0, "locationType" : "DEPOT", "location" : { "makani" : "", "lat" : 25.123091, "lng" : 55.21082 }, "deliveryDays" : "MTWRFSU", "timeWindow" : { "timeWindowTypeId" : "1" }, "address1" : "", "address2" : "", "phone" : "", "city" : "", "county" : "", "state" : "", "country" : "", "zipcode" : "", "imageUrl" : "", "contact" : { "name" : "", "email" : "" }, "status" : "", "createdBy" : "", "updatedBy" : "", "updateDate" : "", "accountId" : 1.0, "serviceTimeTypeId" : "1" } }
-
==============================
5.$ 조회 및 후속 $ 그룹과 집계하면 노드 몽구스 또는 스키마에 몇 가지 힌트와 지원 라이브러리를 사용하고 당신은 그를 가져 오기 위해 .populate ()를 사용할 수 있습니다 (즉, 매체의 경우는 그리고) 그렇다면, 꽤 복잡 서류:
$ 조회 및 후속 $ 그룹과 집계하면 노드 몽구스 또는 스키마에 몇 가지 힌트와 지원 라이브러리를 사용하고 당신은 그를 가져 오기 위해 .populate ()를 사용할 수 있습니다 (즉, 매체의 경우는 그리고) 그렇다면, 꽤 복잡 서류:
var mongoose = require("mongoose"), Schema = mongoose.Schema; var productSchema = Schema({ ... }); var orderSchema = Schema({ _id : Number, products: [ { type: Schema.Types.ObjectId, ref: "Product" } ] }); var Product = mongoose.model("Product", productSchema); var Order = mongoose.model("Order", orderSchema); ... Order .find(...) .populate("products") ...
-
==============================
6.나는 우리가 $ 매치 단계로 서문 경우 우리가 ID를 배열로 $ 조회 작업을 할 수 있습니다, 동의해야합니다.
나는 우리가 $ 매치 단계로 서문 경우 우리가 ID를 배열로 $ 조회 작업을 할 수 있습니다, 동의해야합니다.
// 조회 결과 아이디 어레이를 대체 [(db.products.aggregate {$ 일치 : {제품 : {$가 존재 : TRUE}}} { 조회 $ { 에서 "제품" localField : "제품" foreignField : "_id" 로 : "productObjects" } } ])
우리는 파이프 라인에 조회 결과를 전달하려는 경우는 더 복잡해진다. 하지만 다시 (이미 @ user12164에 의해 제안) 그렇게 할 수있는 방법이있다 :
// 파이프 라인에 전달 조회 결과 아이디 어레이를 대체 [(db.products.aggregate {$ 일치 : {제품 : {$가 존재 : TRUE}}} { 조회 $ { 에서 "제품" 보자 {제품 : "$ 제품"}, 파이프 라인 : {$ 일치 : {$ EXPR : {$에서 : [ "$ _id", "$$ 제품"]}}} {$ 프로젝트 : {_id : 0}} // 억제 _id ], 로 : "productObjects" } } ])
from https://stackoverflow.com/questions/34967482/lookup-on-objectids-in-an-array by cc-by-sa and MIT license
'MONGODB' 카테고리의 다른 글
[MONGODB] MongoDB를 : 그것은 대소 문자를 구분하지 쿼리를 만들 수 있습니까? (0) | 2019.11.29 |
---|---|
[MONGODB] $ 풀림없이 여러 수준을 조회 $? (0) | 2019.11.29 |
[MONGODB] 어떻게 NodeJs 응용 프로그램 및 모듈에서 MongoDB를 적절히 재사용 연결에 (0) | 2019.11.29 |
[MONGODB] 몽구스 통해 몽고 배열 푸시 상품 (0) | 2019.11.29 |
[MONGODB] 여러 필드 MongoDB에 의해 기 값 (0) | 2019.11.29 |