我正在创建一个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]}
]
现在它工作得很好,我可以很容易地通过结果过滤产品,而且它是动态的(我可以只添加一个属性到产品,就这样)。
问题是它的可扩展性非常差,因为:
我的问题是我怎样才能做得更好?我有一个节点服务器,所以把所有的逻辑都移到那里是没有用的,我也可以把“属性收集”功能移到一个工作线程,但同样,我必须查询所有的产品。。。
您可以让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,一个返回结果的新端点
第二:接收初始产品集的无筛选请求
第三:当选择一个过滤器(基于第一个请求)时,你用所选的过滤器做一个新的请求