简体   繁体   English

mongoDB - 聚合后按 id 查找

[英]mongoDB - find by id after aggregation

i have an a nested array.我有一个嵌套数组。 preformed aggregation to make the subarray the new root.执行聚合以使子数组成为新的根。

Category.aggregate([{$unwind: "$SubCats"}, { $replaceRoot: {newRoot: '$SubCats'}} ])

now i need to find by id.现在我需要通过 id 查找。

using this would return empty reuslts:使用它会返回空结果:

Category.aggregate([{$unwind: "$SubCats"}, { $replaceRoot: {newRoot: '$SubCats'}}, {$match: {_id: `${req.params.id}`}} ])

using $elemMatch is not supported for my atlas tier.我的 atlas 层不支持使用$elemMatch and using findById() gives this erro 'Category.aggregate(...).findById is not a function'并使用findById()给出了这个错误'Category.aggregate(...).findById is not a function'

array:大批:

[
 {
     _id: '61cae5daf5bfbebd7cf748ee'
     title: 'category 1',
     SubCats: [
         {
             _id: '61cae5daf5bfbebd7cf748ef'
             name: 'subcat 1',
             image: '/assets/images/vr-box-6203301_1920.jpg',
         },
         {
             _id: '61cae5daf5bfbebd7cf748fb'
             name: 'subcat 2',
             image: '/assets/images/galaxy-s20_highlights_kv_00.jpg',
         },
     ]
 },
]

after aggregation:聚合后:

[
 {
   _id: '61cae5daf5bfbebd7cf748ef'
   name: 'subcat 1',
   image: '/assets/images/vr-box-6203301_1920.jpg',
 },
 {
    _id: '61cae5daf5bfbebd7cf748fb'
    name: 'subcat 2',
    image: '/assets/images/galaxy-s20_highlights_kv_00.jpg',
 },
]

Why not just move the $match stage to be at the start of the pipeline?为什么不将$match阶段移到管道的开头? it will also improve the pipeline's performance as you won't unwind and replace root on many irrelevant documents:它还将提高管道的性能,因为您不会在许多不相关的文档上展开和替换 root:

Category.aggregate([ {$match: {_id: `${req.params.id}`}}, {$unwind: "$SubCats"}, { $replaceRoot: {newRoot: '$SubCats'}} ])

If for some reason you don't want to do this then you have to preserve the original id field throughout the pipeline, specifically through the $replaceRoot stage, like so:如果由于某种原因您不想这样做,那么您必须在整个管道中保留原始 id 字段,特别是通过$replaceRoot阶段,如下所示:

Category.aggregate([
    {
        $unwind: "$SubCats"
    },
    {
        $replaceRoot: {
            newRoot: {
                $mergeObjects: [
                    '$SubCats',
                    { original_id: "$_id" }
                ]
            }
        }
    },
    {
        $match: {original_id: `${req.params.id}`}
    }
])

Field _id is an ObjectId , thus the query must be like this:字段_id是一个ObjectId ,因此查询必须是这样的:

Category.aggregate([
   { $unwind: "$SubCats" }, 
   { $replaceRoot: {newRoot: '$SubCats'} }, 
   { $match: {_id: ObjectId(`${req.params.id}`) } } 
])

But you simply use但你只需使用

Category.aggregate([
   { $match: {"SubCats._id": ObjectId(`${req.params.id}`) } } 
])

or use $filter或使用$filter

Category.aggregate([
   {
      $set: {
         SubCats: {
            $filter: {
               input: "$SubCats",
               cond: { $eq: ["$$this._id", ObjectId(`${req.params.id}`)] }
            }
         }
      }
   }
])

so i needed to install mongodb from npm i didnt have it installed intially because i was conncting to a cloud mongodb databasse.所以我需要从 npm 安装 mongodb 我最初没有安装它,因为我正在连接到云 mongodb 数据库。

so所以

npm i mongodb

then import然后导入

import mongodb from 'mongodb'
const {ObjectId} = mongodb

and then this is what worked:然后这就是有效的:

Category.aggregate([{$unwind: "$SubCats"}, { $replaceRoot: {newRoot: '$SubCats'}}, {$match: {_id: ObjectId(req.params.id)} } ])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM