如何在$ match聚合中找到值数组并将结果分组? [英] how can I find an array of values in a $match aggregation and group the result?

查看:135
本文介绍了如何在$ match聚合中找到值数组并将结果分组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意:我认为无法在此实时编辑器中使用javascript代码

这是我的实时代码: https://mongoplayground.net/p/IM4rY2K7Alt

我是Mongodb的新手,我有足够的信心去理解本练习,以进一步了解aggregations

的主题.

我的问题是这个.我有一个具有这样结构的集合:

[
      {
        "toystore": 22,
        "toystore_name": "Toystore A",
        "toys": [
          {
            "toy": "buzz",
            "code": 17001,
            "price": 500
          },
          {
            "toy": "woddy",
            "code": 17002,
            "price": 1000
          },
          {
            "toy": "pope",
            "code": 17003,
            "price": 300
          }
        ]
      },
      {
        "toystore": 11,
        "toystore_name": "Toystore B",
        "toys": [
          {
            "toy": "jessie",
            "code": 17005,
            "price": 500
          },
          {
            "toy": "rex",
            "code": 17006,
            "price": 2000
          }
        ]
      }
    ]

我有n个玩具店,并且在每个玩具店中,我都有toys字段(是array)中该商店可用的玩具.

我收到了要在所有商店中寻找的玩具清单,并量化了需要报价的玩具.

 var originalData=[       
        {
          "toys.code": 17001,
          "quantify":2
        },
        {
          "toys.code": 17003,
          "quantify":4
        },
        {
          "toys.code": 17005,
          "quantify":5
        },
        {
          "toys.code": 17005,
          "quantify":6
        }
 ]

我正在使用javascript,因此我设法创建了一个像这样的数组:

 let filters = [];
  originalData.forEach((data) => {
    filters.push({ "toys.code": data.code });
  });
//output
filters= [
    {
      "toys.code": 17001
    },
    {
      "toys.code": 17003
    },
    {
      "toys.code": 17005
    },
    {
      "toys.code": 17005
    }
  ]

//in the live code I do this simulation
/*$match: {
  $or: filters
}*/

/*$match: {
      $or: [
        {
          "toys.code": 17001
        }, {
          "toys.code": 17003
        }, {
          "toys.code": 17005
        }, {
          "toys.code": 17005
        }
      ],*/

搜索玩具(我通过玩具代码toys.code搜索玩具),这是我的第一个问题,我不知道如何通过quantity然后获得玩具的总价

(price_total: {$ multiply: [" $toys.price", quantify]})

我想按商店对结果进行分组,并显示商店引用了多少玩具,其输出如下:

[
  {
    "_id": "Toystore A",
    "total_coincidences":2
    "toy_array": [
      {
        "total":1,//  "total":1, //1 time is founded this toy in array filter
        "price_original": 500,
        "toy": "buzz",
        "price_total":1000 
        // 2 * 500=1000  (price total)
      },
      {
        "total":1,//  "total":1, //1 time is founded this toy in array filter
        "price_original": 300,
        "toy": "pope",
        "price_total":1200 
        // 4 * 300= 1200(price total)
      }
    ]
  },
  {
    "_id": "Toystore B",
     "total":1, //1 element distinct is founded

    "toy_array": [
      {
        "total":2, //two times is founded this toy in array filter
        "price_original": 500,
        "toy": "jessie"
        "price_total":5500 
        //this toy is two times in the filter array
        // 5 * 500 = 2500
        // 6 * 500  = 3000
        //3000+ 2500=5500 (price total)
      }
    ]
  }
]

这是我的代码:

db.collection.aggregate([
      {
        $unwind: "$toys"
      }, {
        $match: {
          $or: [
            {
              "toys.code": 17001
            }, {
              "toys.code": 17003
            }, {
              "toys.code": 17005
            }, {
              "toys.code": 17005
            }
          ], 
        }
      }, {
        $group: {
          _id: "$toystore_name", toy_array: {
            $push: {
              price_original: "$toys.price", 
              /* price_total: { $multiply: ["$toys.price", qunantify] }*/
              toy: "$toys.toy"
            }, 
          }, 
        }, 
      }, 
    ])

这是我的实时代码:

解决方案

您需要如下所示更改filters.

说明

  1. 我们使用$addFields运算符将过滤器包含在文档结构中.这将帮助我们计算所有必要的值.
  2. 我们使用$expr运算符使用最近包含的filters属性过滤toys.
  3. 应用$filter运算符,从filters中获得所有具有相同code的玩具.现在,我们可以计算totalprice_total值.
  4. 我们可以像这样在$group阶段内计算total_coincidences:

    total_coincidences:{$ sum:1}

但是,您提到了独特元素".因此,我们创建了一组唯一的玩具代码并计算了其中的项目.


db.collection.aggregate([
  {
    $unwind: "$toys"
  },
  {
    $addFields: {
      "filters": [
        {
          "code": 17001,
          "quantify": 2
        },
        {
          "code": 17003,
          "quantify": 4
        },
        {
          "code": 17005,
          "quantify": 5
        },
        {
          "code": 17005,
          "quantify": 6
        }
      ]
    }
  },
  {
    $match: {
      $expr: {
        $in: [ "$toys.code", "$filters.code"]
      }
    }
  },
  {
    $group: {
      _id: "$toystore_name",
      total_coincidences: {
        $addToSet: "$toys.code"
      },
      toy_array: {
        $push: {
          "price_original": "$toys.price",
          "toy": "$toys.toy",
          "total": {
            $size: {
              $filter: {
                input: "$filters",
                cond: {
                  $eq: [ "$$this.code", "$toys.code"]
                }
              }
            }
          },
          price_total: {
            $sum: {
              $map: {
                input: {
                  $filter: {
                    input: "$filters",
                    cond: {
                      $eq: [ "$$this.code", "$toys.code" ]
                    }
                  }
                },
                in: {
                  $multiply: [ "$toys.price", "$$this.quantify" ]
                }
              }
            }
          }
        }
      }
    }
  },
  {
    $addFields: {
      total_coincidences: {
        $size: "$total_coincidences"
      }
    }
  },
  {
    $sort: { _id: 1 }
  }
])

MongoPlayground

Note:I think it is not possible to use javascript code in this live editor

this is my live code: https://mongoplayground.net/p/IM4rY2K7Alt

I am new to Mongodb I have a lot of faith to understand this exercise to understand more about the topic ofaggregations

My problem is this. I have a collection with a structure like this:

[
      {
        "toystore": 22,
        "toystore_name": "Toystore A",
        "toys": [
          {
            "toy": "buzz",
            "code": 17001,
            "price": 500
          },
          {
            "toy": "woddy",
            "code": 17002,
            "price": 1000
          },
          {
            "toy": "pope",
            "code": 17003,
            "price": 300
          }
        ]
      },
      {
        "toystore": 11,
        "toystore_name": "Toystore B",
        "toys": [
          {
            "toy": "jessie",
            "code": 17005,
            "price": 500
          },
          {
            "toy": "rex",
            "code": 17006,
            "price": 2000
          }
        ]
      }
    ]

I have n toy stores, and within each toy store I have the toys that this store has available within thetoys field (is an array).

I receive a list of the toys that I want to look for in all the stores and the quantify of toys that I need to quote.

 var originalData=[       
        {
          "toys.code": 17001,
          "quantify":2
        },
        {
          "toys.code": 17003,
          "quantify":4
        },
        {
          "toys.code": 17005,
          "quantify":5
        },
        {
          "toys.code": 17005,
          "quantify":6
        }
 ]

I'm using javascript, so I manage to create an array like this:

 let filters = [];
  originalData.forEach((data) => {
    filters.push({ "toys.code": data.code });
  });
//output
filters= [
    {
      "toys.code": 17001
    },
    {
      "toys.code": 17003
    },
    {
      "toys.code": 17005
    },
    {
      "toys.code": 17005
    }
  ]

//in the live code I do this simulation
/*$match: {
  $or: filters
}*/

/*$match: {
      $or: [
        {
          "toys.code": 17001
        }, {
          "toys.code": 17003
        }, {
          "toys.code": 17005
        }, {
          "toys.code": 17005
        }
      ],*/

to search for toys (I search for toys by their code toys.code), here I have my first problem, I don't know how to pass thequantity and then get the total price of the toys

(price_total: {$ multiply: [" $toys.price", quantify]})

I would like to group the result by store, and show how many toys were quoted by store with an output like this:

[
  {
    "_id": "Toystore A",
    "total_coincidences":2
    "toy_array": [
      {
        "total":1,//  "total":1, //1 time is founded this toy in array filter
        "price_original": 500,
        "toy": "buzz",
        "price_total":1000 
        // 2 * 500=1000  (price total)
      },
      {
        "total":1,//  "total":1, //1 time is founded this toy in array filter
        "price_original": 300,
        "toy": "pope",
        "price_total":1200 
        // 4 * 300= 1200(price total)
      }
    ]
  },
  {
    "_id": "Toystore B",
     "total":1, //1 element distinct is founded

    "toy_array": [
      {
        "total":2, //two times is founded this toy in array filter
        "price_original": 500,
        "toy": "jessie"
        "price_total":5500 
        //this toy is two times in the filter array
        // 5 * 500 = 2500
        // 6 * 500  = 3000
        //3000+ 2500=5500 (price total)
      }
    ]
  }
]

this is my code:

db.collection.aggregate([
      {
        $unwind: "$toys"
      }, {
        $match: {
          $or: [
            {
              "toys.code": 17001
            }, {
              "toys.code": 17003
            }, {
              "toys.code": 17005
            }, {
              "toys.code": 17005
            }
          ], 
        }
      }, {
        $group: {
          _id: "$toystore_name", toy_array: {
            $push: {
              price_original: "$toys.price", 
              /* price_total: { $multiply: ["$toys.price", qunantify] }*/
              toy: "$toys.toy"
            }, 
          }, 
        }, 
      }, 
    ])

and this is my live code:

解决方案

You need to change your filters as shown below.

Explanation

  1. We include filters in the document structure with the $addFields operator. This will help us calculate all the necessary values.
  2. We filter toys with the recent included filters attribute with the $expr operator.
  3. Applying the $filter operator, we get all toys with the same code from filters. Now, we can calculate total and price_total values.
  4. We could calculate total_coincidences inside the $group stage like this:

    total_coincidences : {$sum:1}

But, you've mentioned "distinct element". So, we create set of unique toy codes and count items in the set.


db.collection.aggregate([
  {
    $unwind: "$toys"
  },
  {
    $addFields: {
      "filters": [
        {
          "code": 17001,
          "quantify": 2
        },
        {
          "code": 17003,
          "quantify": 4
        },
        {
          "code": 17005,
          "quantify": 5
        },
        {
          "code": 17005,
          "quantify": 6
        }
      ]
    }
  },
  {
    $match: {
      $expr: {
        $in: [ "$toys.code", "$filters.code"]
      }
    }
  },
  {
    $group: {
      _id: "$toystore_name",
      total_coincidences: {
        $addToSet: "$toys.code"
      },
      toy_array: {
        $push: {
          "price_original": "$toys.price",
          "toy": "$toys.toy",
          "total": {
            $size: {
              $filter: {
                input: "$filters",
                cond: {
                  $eq: [ "$$this.code", "$toys.code"]
                }
              }
            }
          },
          price_total: {
            $sum: {
              $map: {
                input: {
                  $filter: {
                    input: "$filters",
                    cond: {
                      $eq: [ "$$this.code", "$toys.code" ]
                    }
                  }
                },
                in: {
                  $multiply: [ "$toys.price", "$$this.quantify" ]
                }
              }
            }
          }
        }
      }
    }
  },
  {
    $addFields: {
      total_coincidences: {
        $size: "$total_coincidences"
      }
    }
  },
  {
    $sort: { _id: 1 }
  }
])

MongoPlayground

这篇关于如何在$ match聚合中找到值数组并将结果分组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆