mon goose find () сортировка и организация возвращаемых результатов из базы данных продуктов в js - PullRequest
0 голосов
/ 27 февраля 2020

У меня проблема с организацией моих данных mongoDB для отправки на мою страницу в моем резюме и я не могу понять, как сделать правильный js. Вот упрощенная версия моей схемы

var productSchema = new mongoose.Schema({

medium:     String,
brand:      String,
group:      String

});

Вот как выглядит типичная запись

 medium :"Acrylic",
 brand  :"liquitex",
 group  :"heavy body"

. В схема, но это единственные, с которыми мне нужно иметь возможность сортировать и организовывать возвращаемые результаты. Проблема в том, что у меня есть маршрут, который возвращает все цвета в моей базе данных, и я хочу иметь возможность отображать их в разделах на моей странице, которые сгруппированы под брендом, а затем отдельные цвета перечислены в правильной группе.

Проблема в том, что есть краски других брендов, которые попадают в группу с тяжелым телом, и поэтому, когда я использую функцию фильтра для сортировки данных по группам, некоторые бренды смешиваются вместе. Я не могу фильтровать по брендам, потому что у некоторых брендов есть акрил c и акварель, поэтому они смешиваются вместе. Мне нужен какой-то способ отфильтровать возвращенные результаты

mongoose.find({})

, который может использовать данные группы в качестве фильтра, но затем отфильтровать эти результаты по брендам, чтобы они были разделены на правильные категории брендов.

Пока у меня есть это:

это урезанная версия моего приложения. js файл:

    //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} );

и это работает хорошо, что я могу отображать каждую краску по ее группировке, но это не удается, если имеется более одной краски от другого производителя, которая считается одной и той же группой как «тяжелое тело». Это моя e js на моей странице, которая отлично работает:

<% colorEntry.forEach( function(entry){ %>                  
                    <div class="brandBlock">                        
                        <div class="brandTitle">
    <span><%=entry.result[0].brand%> - <%=entry.result[0].group%></span> 

Я, по жизни, не могу понять комбинацию filter () и, возможно, map (), которая позволила бы такого рода обработки будет сделано. В моей базе данных около 600 документов, цветов от разных производителей, и я не знаю, как получить это как возвращаемую структуру: допустим, это несколько цветов в БД, которые возвращаются из mon goose find:

[{ medium: "Oil",
   brand: "Gamblin",
   group: "Artists oil colors"},
 { medium: "Acrylic",
   brand: "Liquitex",
   group:  "Heavy Body"},
 { medium: "Acrylic",
   brand: "Golden",
   group: "Heavy Body"}
]

Мне нужно организовать это так или что-то подобное. Это может быть что угодно, что просто сортирует эти данные в базовую c структуру, подобную этой, я не ограничен каким-либо установленным стандартом или чем-то еще, это только для личного использования, и сайт, который я пытаюсь создать, чтобы узнать больше.

 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 дней. Я не могу обернуть голову вокруг некоторых удивительных комбо фильтров и карт, которые я видел, и не могу заставить это работать. Любая помощь или совет будут великолепны. Я уверен, что есть много областей для улучшения этого кода, но все работало до тех пор, пока я не ввел краски от разных брендов, имеющих одинаковый тип группы, и мне пришлось попытаться переписать этот код сортировки, чтобы справиться с ним. Это сводится к необходимости иметь возможность перебирать весь набор возвращаемых документов из БД, а затем сортировать их по двум значениям.

ОБНОВЛЕНИЕ: Мне удалось получить что-то, что работает и возвращает данные в формате, который мне нужен, чтобы иметь возможность отправить их в мой файл e js и правильно отобразить их. Код довольно уродливый и, вероятно, очень избыточный, но он технически работает. Он начинается с использования значения группы для запуска над красками, поскольку каждый набор красок будет иметь имя группы, но иногда может использовать имя группы совместно с краской другой марки, такой как «тяжелое тело».

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

Благодаря ответу ниже, я был на правильном пути и смог переписать кучу этого длинного кода следующим образом:

    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()} );
    }       
});

Значительно чище и, похоже, достиг того же результата.

1 Ответ

0 голосов
/ 28 февраля 2020

Поскольку вы используете MongoDB, «правильный» способ - использовать структуру агрегирования , точнее, $ group stage.

Product.aggregate([{
    $group: {
        _id: { group: '$group', brand: '$brand' },
        products: { $push: '$$ROOT' }
    }
}])

Это выведет массив объектов, содержащих каждую комбинацию бренда и группы, и pu sh всех соответствующих продуктов в соответствующий подмассив.

Объедините его с $ project и $ sort этапы для дальнейшей обработки ваших данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...