如何从对象数组返回匹配的文档

时间:2020-09-23 08:37:59

标签: mongodb mongoose

我正在尝试根据价格从产品集中过滤产品。

当前产品系列:

[
{
  _id: ObjectId("56f277b1279871c20b8b4566"),
  product_name:'sample product 1',
  product_items:[
         {
            product_price: 50.99,
            product_item_no: '123456789',
            product_images:['default.png']
          },
          {
            product_price: 11.99,
            product_item_no: '683456789',
            product_images:['default2.png']
          }
       ],
       product_status_is_active: true,

},
{
  _id: ObjectId("56f277b1279871c20b8b4567"),
  product_name:'sample product 2',
  product_items:[
         {
            product_price: 12.99,
            product_item_no: '45678923',
            product_images:['default2.png']
          },
          {
            product_price: 66.99,
            product_item_no: '683456789',
            product_images:['default4.png']
          }
       ],
       product_status_is_active: true,
}
]

猫鼬查询:

{
     '$match': {
       product_status_is_active: true,
       product_items: { '$elemMatch': { product_price: { '$gte': 60, '$lte': 100 } } }
    }
  },

当前输出:

{
  _id: ObjectId("56f277b1279871c20b8b4567"),
  product_name:'sample product 2',
  product_items:[
         { // This object should not display
            product_price: 12.99,
            product_item_no: '45678923',
            product_images:['default2.png']
          },
          {
            product_price: 66.99,
            product_item_no: '683456789',
            product_images:['default4.png']
          }
       ],
       product_status_is_active: true,
}

预期输出如下:

{
  _id: ObjectId("56f277b1279871c20b8b4567"),
  product_name:'sample product 2',
  product_items:[
          {
            product_price: 66.99,
            product_item_no: '683456789',
            product_images:['default4.png']
          }
       ],
       product_status_is_active: true,
}

但是我查询的输出还包含不匹配的product_price。

如何强制MongoDB仅返回与查询匹配的product_price?

问候和感谢。

1 个答案:

答案 0 :(得分:1)

您可以通过聚合来实现。

  1. 匹配product_status_is_active:true
  2. 使用$filter根据条件过滤数组
  3. 将老化匹配为空的product_items数组

聚合阶段是

[
  {
    $match: {
      "product_status_is_active": true
    }
  },
  {
    $addFields: {
      product_items: {
        $filter: {
          input: "$product_items",
          cond: {
            $and: [
              {
                $gte: [
                  "$$this.product_price",
                  60
                ]
              },
              {
                $lte: [
                  "$$this.product_price",
                  100
                ]
              }
            ]
          }
        }
      }
    }
  },
  {
    $match: {
      product_items: {
        $ne: []
      }
    }
  }
]

工作Mongo playground