bestsource

Moongoose 집계 $match가 ID와 일치하지 않습니다.

bestsource 2023. 5. 29. 11:02
반응형

Moongoose 집계 $match가 ID와 일치하지 않습니다.

ID별로 제품을 보여주고 싶습니다(56e641d4864e5b780bb992c6그리고.56e65504a323ee0812e511f2) 및 가능한 경우 할인으로 뺀 후 가격을 표시합니다.

집계를 사용하여 최종 가격을 계산할 수 있지만 컬렉션의 모든 문서를 반환합니다. 일치 ID만 반환하는 방법

"_id" : ObjectId("56e641d4864e5b780bb992c6"), 
"title" : "Keyboard", 
"discount" : NumberInt(10),
"price" : NumberInt(1000)

"_id" : ObjectId("56e65504a323ee0812e511f2"), 
"title" : "Mouse", 
"discount" : NumberInt(0),
"price" : NumberInt(1000)

"_id" : ObjectId("56d90714a48d2eb40cc601a5"), 
"title" : "Speaker", 
"discount" : NumberInt(10),
"price" : NumberInt(1000)

이것은 나의 질문입니다.

productModel.aggregate([
        {
            $project: {
                title   : 1,
                price: {
                    $cond: {
                        if: {$gt: ["$discount", 0]}, then: {$subtract: ["$price", {$divide: [{$multiply: ["$price", "$discount"]}, 100]}]}, else: "$price"
                    }

                }
            }
        }
    ], function(err, docs){
        if (err){
            console.log(err)
        }else{
            console.log(docs)
        }
    })

그리고 이것을 더하면,$in쿼리, 빈 배열을 반환합니다.

productModel.aggregate([
            {
                $match: {_id: {$in: ids}}
            },
            {
                $project: {
                    title   : 1,
                    price: {
                        $cond: {
                            if: {$gt: ["$discount", 0]}, then: {$subtract: ["$price", {$divide: [{$multiply: ["$price", "$discount"]}, 100]}]}, else: "$price"
                    }

                }
            }
        }
    ], function(err, docs){
        if (err){
            console.log(err)
        }else{
            console.log(docs)
        }
    })

당신의.ids변수는 "variable"로 구성되며, 그렇지 않습니다.ObjectId가치.

Mongoose "autocasts" 문자열 값:ObjectId일반 쿼리에서 올바른 유형으로 입력되지만 문제 #1399에서 설명한 것처럼 집계 파이프라인에서는 이러한 작업이 발생하지 않습니다.

대신 올바른 주조를 수행하여 수동으로 입력해야 합니다.

ids = ids.map(function(el) { return mongoose.Types.ObjectId(el) })

그런 다음 파이프라인 단계에서 사용할 수 있습니다.

{ "$match": { "_id": { "$in": ids } } }

그 이유는 집계 파이프라인이 "일반적으로" 문서 구조를 변경하기 때문이며, 따라서 mongoose는 주어진 파이프라인 단계에서 "schema"가 문서에 적용된다고 가정하지 않습니다.

그것이 "첫 번째" 파이프라인 단계일 때 논쟁의 여지가 있습니다.$match실제로 문서가 변경되지 않았기 때문에 스테이지는 이 작업을 수행해야 합니다.하지만 지금은 이런 일이 일어나지 않습니다.

문자열일 수도 있고 적어도 올바른 BSON 유형이 아닐 수도 있는 모든 값을 일치시키려면 수동으로 캐스트해야 합니다.

  1. 몽구스에서는 find({_id:'606c1ceb362b366a841171dc'})와 잘 작동합니다.

  2. 그러나 집계 함수를 사용하는 동안 우리는 _id를 객체로 변환하기 위해 mongoose 객체를 사용해야 합니다.

$match: {"_id": 몽구스.Types.ObjectId("606c1ceb362b366a841171dc") }

이것은 잘 될 것 같아요.

ID를 다음으로 변환할 수 있습니다.

 let id = mongoose.Types.ObjectId(req.query.id);

그다음에

 { $match: { _id: id } },

다음 대신:

$match: { _id: "6230415bf48824667a417d56" }

사용:

$match: { _id: ObjectId("6230415bf48824667a417d56") }

사용

$match: { $in : [ {_id: mongoose.Types.ObjectId("56e641d4864e5b780bb992c6 ")}, {_id: mongoose.Types.ObjectId("56e65504a323ee0812e511f2")}] }

Mongoose는 ObjectId에 대한 문자열 값을 일반 쿼리에서 올바른 유형으로 자동 캐스트하지만 집계 파이프라인에서는 이 작업이 수행되지 않습니다.따라서 파이프라인 쿼리에서 ObjectId 캐스트를 정의해야 합니다.

언급URL : https://stackoverflow.com/questions/36193289/moongoose-aggregate-match-does-not-match-ids

반응형