提问者:小点点

如何在Node.js和Angular中高效创建“产品过滤器”?


我正在创建一个angular应用程序(计算机在线商店)与一个Node/Express后台。我有一个产品页面显示我的数据库中的所有产品。一个产品有这样的模型(打字稿):

interface Product {
  name: string
  properties: {name: string, value: string | number}[]
}

我有一个部分在页面内,你可以过滤产品的属性。例如,用户可以过滤所有具有4核或8核的CPU。现在它是这样实现的:

在angular应用程序中,我查询所请求类别的所有产品,循环遍历所有产品,收集它们的属性和所有可能的值,然后像下面这样筛选。。。

const products = [
{
  name: 'intel cpu 1',
  properties: [
    {name: 'cores', value: 8},
    {name: 'clock speed', value: 2.6}
  ]
},
{
  name: 'intel cpu 2',
  properties: [
    {name: 'cores', value: 4},
    {name: 'clock speed', value: 1.2}
  ]
}
]

collectPropertiesFromProducts(products)

// RESULT: 
[
  {property: 'cores', possibleValues: [4,8]},
  {property: 'clock speed', possibleValues: [1.2,2.6]}
]

现在它工作得很好,我可以很容易地通过结果过滤产品,而且它是动态的(我可以只添加一个属性到产品,就这样)。

问题是它的可扩展性非常差,因为:

  • 我必须查询所有产品以了解它们的属性
  • 产品/属性越多=CPU时间越多=阻塞主线程

我的问题是我怎样才能做得更好?我有一个节点服务器,所以把所有的逻辑都移到那里是没有用的,我也可以把“属性收集”功能移到一个工作线程,但同样,我必须查询所有的产品。。。


共2个答案

匿名用户

您可以让mongodb为您进行计算,而不是在客户机或服务本身中处理这个问题。例如。您可以编写以下聚合:

db.getCollection('products').aggregate([{
            $unwind: "$properties"
        },
        {
            $project: {
                name: "$properties.name",
                total: {
                    $add: ["$properties.value", ]
                }
            }
        }, {
            $group: {
                _id: "$name",
                possibleValues: {
                    $addToSet: "$total"
                }
            }
        }

    ])

然后可以通过节点服务器上的自定义端点(例如get/product-properties)公开此查询,并在客户端上使用响应。

匿名用户

您应该考虑对后端执行多个请求:

第一个:getQueryParams,一个返回结果的新端点

第二:接收初始产品集的无筛选请求

第三:当选择一个过滤器(基于第一个请求)时,你用所选的过滤器做一个新的请求