首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在js中对来自产品数据库的返回结果进行排序和组织

在js中对来自产品数据库的返回结果进行排序和组织
EN

Stack Overflow用户
提问于 2020-02-27 05:15:20
回答 1查看 268关注 0票数 0

我在组织我的mongoDB数据发送到我的res页面时遇到了问题,并且无法想出如何做正确的js。下面是我的模式的简化版本

代码语言:javascript
复制
var productSchema = new mongoose.Schema({

medium:     String,
brand:      String,
group:      String

});

下面是一个典型的条目

代码语言:javascript
复制
 medium :"Acrylic",
 brand  :"liquitex",
 group  :"heavy body"

模式中还有更多的条目,但只有这些条目才能对返回的结果进行排序和组织。问题是,我有一条返回数据库中所有颜色的路径,我希望能够在我的页面中按“品牌”分组显示它们,然后在正确的组下列出各个颜色。

问题是来自其他品牌的油漆属于重体组,所以当我使用过滤函数按组对数据进行排序时,一些品牌就混合在一起。我不能按品牌过滤,因为有些品牌有丙烯酸和水彩画,所以它们就聚在一起了。我需要某种方法来过滤

mongoose.find({})

它可以使用组数据作为筛选器,但随后根据品牌过滤这些结果,从而将其划分为正确的品牌类别。

到目前为止,我有这样的看法:

这都是我的app.js文件的简化版本:

代码语言:javascript
复制
    //finds all colors in the DB
    Color.find({}).lean().exec(function( err, colors)

                var groups  = [];
                // find all groups in the databse
                colors.forEach( function(color){    
                    groups.push(color["group"]);
                }); 


    //returns only unique names to filter out duplicates
                var groupTypes  = Array.from(new Set(groups));



            var tempVariableBrands = [];
// this sorts all returned paints into their respective group, but we get paints from multiple brands under the same group and that is not good
            groupTypes.forEach( function(group){
                            var name = group;
                            var result = colors.filter(obj => { return obj.group === group });
                            tempVariable.push(  {group : name, result } );      
                        });


        // the tempVariable gets sent to my page like so
        res.render("landing", {colorEntry:tempVariable} );

这可以很好的让我按照自己的分组来显示每一种油漆,但是当一个不同的制造商有不止一种油漆被认为是同一组,就像一个“笨重的身体”时,它就失败了。这是我页面上运行良好的ejs:

代码语言:javascript
复制
<% colorEntry.forEach( function(entry){ %>                  
                    <div class="brandBlock">                        
                        <div class="brandTitle">
    <span><%=entry.result[0].brand%> - <%=entry.result[0].group%></span> 

在我的一生中,我似乎无法找到过滤器()和可能map()的组合,这样就可以完成这种处理。我的数据库有大约600个文档,来自许多不同制造商的颜色,我不知道如何将其作为返回的结构:让我们说,这是DB中从猫鼬中返回的几种颜色:

代码语言:javascript
复制
[{ medium: "Oil",
   brand: "Gamblin",
   group: "Artists oil colors"},
 { medium: "Acrylic",
   brand: "Liquitex",
   group:  "Heavy Body"},
 { medium: "Acrylic",
   brand: "Golden",
   group: "Heavy Body"}
]

我需要像这样或者类似的东西来组织它。它可以是任何东西,只是将这些数据分类成这样的基本结构,我不局限于任何设定的标准或任何东西,这只是个人使用和一个网站,我想要了解更多。

代码语言:javascript
复制
 returnedColors = [ { brand: "Gamblin", group: "Artists oil colors", { 50 paints colors returned} },
                    { brand: "liquitex" , group: "heavy body", { 20 paint colors returned } },
                    { brand:  "golden"  , group: "heavy body",{ 60 paint colors returned} }
                  ];

我不是一个网页开发人员,只写一些网页代码每6个月左右,并一直在尝试如何解决这个问题在过去2天。我不能把我的头包围在一些令人敬畏的过滤器和地图组合中,我已经看过了,也无法让它发挥作用。任何帮助或建议都会很好。我相信在这个代码中有很多地方需要改进,但是所有的事情都在进行,直到我输入了来自不同品牌、具有相同组类型的油漆,我不得不尝试重写这个排序代码来处理它。归根结底,它需要能够迭代从DB返回的全部文档,然后根据2个值对它们进行排序。

更新:能够获得一些有用的信息,并以所需的格式返回数据,以便将其发送到ejs文件并正确显示。这段代码很难看,而且可能非常冗余,但在技术上是可行的。它首先使用组值来遍历油漆,因为每一组油漆都有一个组名,但有时可以与另一个品牌的油漆共享一个组名,比如"heavy“。

代码语言:javascript
复制
groupTypes.forEach( function(group){
                    var name = group;
                    var result = colors.filter(obj => { return obj.group === group });                  

                    // this gets brand names per iteration of this loop so that we will know if more than one brand of paint
                    // has the same group identity.
                    var brands  = [];
                    result.forEach( function(color){    
                        brands.push(color["brand"]);    
                    }); 
                    // This filters the brand names down to a unique list of brands
                    var brandNames  = Array.from(new Set(brands));

                    // if there is more than one brand, we need to filter this into two separate groups

                    if( brandNames.length > 1){
                        //console.log("You have duplicates");

                        brandNames.forEach( x => {
                            var tmpResult = [...result];
                            var resultTmp = result.filter(obj => { return obj.brand === x });

                            result = resultTmp;
                            //console.log("FILTERED RESULT IS: ", result);
                            tempVariable.push(  {brand: x ,group : name, result } );
                            result  = [...tmpResult];
                        });
                    }else{                      
                        tempVariable.push(  {brand: result[0].brand ,group : name, result } );
                    }
                });

如果有人能将其简化为更有效的方法,我希望看到“更好”或“正确”的方式来做这样的事情。

UPDATE2

由于下面的答案,我走上了正确的轨道,并且能够用下面的代码重写一堆长代码:

代码语言:javascript
复制
    Color.aggregate([       
    {
        $sort: { name: 1}
    },
    {
        $group: {
            _id: { brand: '$brand', group: '$group' },
            result: { $push: '$$ROOT' }
        }
    },
    { $sort: { '_id.brand': 1 } }

    ], function( err, colors){
    if(err){
        console.log(err);
    }else{
        res.render("landing", {colorEntry:colors, isSearch:1, codes: userCodes, currentUser: req.user, ads: vs.randomAds()} );
    }       
});

要干净得多,似乎也能达到同样的效果。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-28 11:49:16

由于您使用的是MongoDB,“正确”的方法就是使用聚合框架,准确地说,是$group阶段。

代码语言:javascript
复制
Product.aggregate([{
    $group: {
        _id: { group: '$group', brand: '$brand' },
        products: { $push: '$$ROOT' }
    }
}])

这将输出包含品牌和组组合的对象数组,并将所有相关产品推送到相应的子数组。

将其与$project$sort阶段相结合,进一步塑造您的数据。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60426641

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档