агрегация монго рассчитывается для каждого документа с наименьшим значением - PullRequest
0 голосов
/ 07 июня 2018

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

Учитывая следующие данные

    { departement : 'C_TG', type : 'FLAT_1', offer: 500, req: 495 }
    { departement : 'D_TG', type : 'FLAT_1', offer: 422, req: 420 }
    { departement : 'F_TG', type : 'FLAT_1', offer: 600, req: 480 }

    { departement : 'C_TG', type : 'FLAT_7', offer: 900, req: 889 }
    { departement : 'D_TG', type : 'FLAT_7', offer: 601, req: 500 }
    { departement : 'F_TG', type : 'FLAT_7', offer: 600, req: 590 }

    { departement : 'C_TG', type : 'FLAT_4', offer: 601, req: 599 }
    { departement : 'D_TG', type : 'FLAT_4', offer: 755, req: 735 }
    { departement : 'F_TG', type : 'FLAT_4', offer: 600, req: 590 }

IЯ пытаюсь найти разницу между «наименьшим» предложением (для каждого типа (например, FLAT_1)) и всеми документами (того же типа).

Поэтому необходимо

  • для каждого типа (например, FLAT_1),
  • найдите наименьшее предложение для этого типа (FLAT_1, в данном случае "offer: 422" из "departement: 'D_TG'")
  • поместите этот "наименьший_фер и его наименьший_отчет" в память ...
  • ... чтобы иметь возможность рассчитать разницу во ВСЕХ наборах одного типа (FLAT_1), например

    (this.docs.req-наименьшее предложение) / (наименьшее предложение / 100) = процентная разница

  • и распечатайте все документы, включая наименьшее_отношение + наименьшее_действие_департамента + разницу

ожидаемый результат, наконец, будет примерно таким:

{ type : "FLAT_1", least_offer : 422, least_offer_departement : "D_TG", departement : "C_TG", req: 495, diff : 17.29 }
{ type : "FLAT_1", least_offer : 422, least_offer_departement : "D_TG", departement : "F_TG", req: 480, diff : 13.74 }
{ type : "FLAT_1", least_offer : 422, least_offer_departement : "D_TG", departement : "D_TG", req: 420 , diff : -0.47 }

{ type : "FLAT_7", least_offer : 600, least_offer_departement : "F_TG", departement : "C_TG", req: 889, diff : 48.16 }
{ type : "FLAT_7", least_offer : 600, least_offer_departement : "F_TG", departement : "F_TG", req: 590, diff : -1.66 }
{ type : "FLAT_7", least_offer : 600, least_offer_departement : "F_TG", departement : "D_TG", req: 500, diff : -16.66 }

{ type : "FLAT_4", least_offer : 600, least_offer_departement : "F_TG", departement : "C_TG", req: 599, diff : -0.16 }
{ type : "FLAT_4", least_offer : 600, least_offer_departement : "F_TG", departement : "F_TG", req: 590, diff : -1.66 }
{ type : "FLAT_4", least_offer : 600, least_offer_departement : "F_TG", departement : "D_TG", req: 735, diff : 22.5 }

best regАрдс, Саймон

1 Ответ

0 голосов
/ 10 июня 2018

woohaa, я сделал это сам ..

Результат немного отличается от того, что я первоначально хотел, но он дает мне информацию, которую я хотел

Хотел поделиться своими выводами, может быть, кто-тоеще может извлечь из этого выгоду.

То, что я сделал:

    db.prices.aggregate ([
        // only offers/request > 0, sometimes we get 0 values ..
        {
            $match : {
                offer : {
                    $gt : 0,
                },
                req : {
                    $gt : 0,
                },
            }
        },
        // sort them, to be able to find least offer
        {
            $sort: {
                'type': 1,
                'offer': 1,
            },
        },
        // then group them by type, and and get the least offer and its departement
        {
            $group: {
                _id: '$type',
                low_offer_departement: {
                    $first: '$departement'
                },
                low_offer: {
                    $first: '$offer'
                },
                // and push the current least offer and department to the document
                request : {
                    $push : {
                        departement : '$departement',
                        request: '$req',
                    }
                },
            }
        },
        // then we unwind "request subdocument" to create new documents, these are many ..
        {
            $unwind : '$request',
        },
        // now I can project and decide what I want to see in the result
        {
            $project : {
                _id : 0,
                request : 1,
                type: '$_id',
                low_offer_departement : '$low_offer_departement',
                low_offer : '$low_offer',
                // for each document, I want the difference between the "lowest offer"
                // and the "current" request
                diff : {
                    $divide : [
                        {
                            $subtract : [
                                '$request.request', '$low_offer'
                            ]
                        }, {
                            $divide : [
                                '$low_offer', 100
                            ]
                        }
                    ]
                }
            }
        },
        // and finally I am only interested in results between 5 and 20%
        {
            $match : {
                diff : {
                    $gt : 5,
                    $lt : 20
                }
            }
        },
        // this sort does not seem to make sense, but the final output is in a
        // table in a terminal, and I dont want too much change/movement in there
        {
            $sort: {
                type: 1
            }
        }
    ]);

, поэтому перед размоткой мы получим следующий результат:

{ "_id" : "FLAT_7", "low_offer_departement" : "F_TG", "low_offer" : 600, "request" : [ { "departement" : "F_TG", "request" : 590 }, { "departement" : "D_TG", "request" : 500 }, { "departement" : "C_TG", "request" : 889 } ] }
{ "_id" : "FLAT_4", "low_offer_departement" : "F_TG", "low_offer" : 600, "request" : [ { "departement" : "F_TG", "request" : 590 }, { "departement" : "C_TG", "request" : 599 }, { "departement" : "D_TG", "request" : 735 } ] }
{ "_id" : "FLAT_1", "low_offer_departement" : "D_TG", "low_offer" : 422, "request" : [ { "departement" : "D_TG", "request" : 420 }, { "departement" : "C_TG", "request" : 495 }, { "departement" : "F_TG", "request" : 480 } ] }

, что пока хорошо, но я хотел разницы, поэтому я решил размотать и продолжить форматировать вывод

после разворачивания и этапа проекта, у меня есть

{ "request" : { "departement" : "F_TG", "request" : 590 }, "type" : "FLAT_7", "low_offer_departement" : "F_TG", "low_offer" : 600, "diff" : -1.6666666666666667 }
{ "request" : { "departement" : "D_TG", "request" : 500 }, "type" : "FLAT_7", "low_offer_departement" : "F_TG", "low_offer" : 600, "diff" : -16.666666666666668 }
{ "request" : { "departement" : "C_TG", "request" : 889 }, "type" : "FLAT_7", "low_offer_departement" : "F_TG", "low_offer" : 600, "diff" : 48.166666666666664 }
{ "request" : { "departement" : "F_TG", "request" : 590 }, "type" : "FLAT_4", "low_offer_departement" : "F_TG", "low_offer" : 600, "diff" : -1.6666666666666667 }
{ "request" : { "departement" : "C_TG", "request" : 599 }, "type" : "FLAT_4", "low_offer_departement" : "F_TG", "low_offer" : 600, "diff" : -0.16666666666666666 }
{ "request" : { "departement" : "D_TG", "request" : 735 }, "type" : "FLAT_4", "low_offer_departement" : "F_TG", "low_offer" : 600, "diff" : 22.5 }
{ "request" : { "departement" : "D_TG", "request" : 420 }, "type" : "FLAT_1", "low_offer_departement" : "D_TG", "low_offer" : 422, "diff" : -0.47393364928909953 }
{ "request" : { "departement" : "C_TG", "request" : 495 }, "type" : "FLAT_1", "low_offer_departement" : "D_TG", "low_offer" : 422, "diff" : 17.298578199052134 }
{ "request" : { "departement" : "F_TG", "request" : 480 }, "type" : "FLAT_1", "low_offer_departement" : "D_TG", "low_offer" : 422, "diff" : 13.744075829383887 }

, так что теперь я могу фильтровать результаты толькополучить действительно интересные вещи

, что в итоге приводит к 2

{ "request" : { "departement" : "C_TG", "request" : 495 }, "type" : "FLAT_1", "low_offer_departement" : "D_TG", "low_offer" : 422, "diff" : 17.298578199052134 }
{ "request" : { "departement" : "F_TG", "request" : 480 }, "type" : "FLAT_1", "low_offer_departement" : "D_TG", "low_offer" : 422, "diff" : 13.744075829383887 }

Я надеюсь, что я не объяснил здесь глупости и никакой неверной информации, если так, терпите меня, я все ещекровавый ублюдок с монго и скоплениями;)

с наилучшими пожеланиями, Саймон

...