Агрегация с минимальным и максимальным количеством различных полей, в т.ч.выход - PullRequest
0 голосов
/ 07 июня 2018

Я надеюсь, что вы можете помочь мне с проблемой, одно из моих первых сообщений, поэтому, пожалуйста, потерпите меня, я сделаю все возможное.

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

{ departement : 'C_TG', type : 'FLAT_1', offer: 500, req: 490 }
{ departement : 'C_TG', type : 'FLAT_1', offer: 600, req: 595 }
{ departement : 'F_TG', type : 'FLAT_1', offer: 600, req: 480 }
{ departement : 'C_TG', type : 'FLAT_7', offer: 900, req: 889 }
{ departement : 'C_TG', type : 'FLAT_1', offer: 460, req: 454 }
{ departement : 'F_TG', type : 'FLAT_4', offer: 600, req: 590 }
{ departement : 'C_TG', type : 'FLAT_4', offer: 601, req: 599 }
{ departement : 'D_TG', type : 'FLAT_1', offer: 422, req: 420 }
{ departement : 'D_TG', type : 'FLAT_7', offer: 600, req: 500 }

Я хотел бы объединить данные, чтобы получить самое низкое предложение и самый высокий запрос (req) для определенного типа, , включая департамент (!!) , который несет за это ответственность.Пример результата:

{ type: 'FLAT_1' offer: 422, offer_departement: 'D_TG', req: 595, req_departement: 'F_TG' }
{ type: 'FLAT_4' offer: 600, offer_departement: 'F_TG', req: 599, req_departement: 'C_TG' }
{ type: 'FLAT_7' offer: 600, offer_departement: 'D_TG', req: 889, req_departement: 'C_TG' }

До сих пор моим лучшим результатом было что-то вроде

[ { _id: { type: "FLAT_1", offer_departement: "D_TG" }, req: 595 } ]

Но здесь вся информация, касающаяся "информации запроса", отсутствовала, поэтому она не имеет смысла.Я уже сгруппировал и отсортировал, также сделал несколько групповых этапов и так далее, но либо я получаю полный список элементов, не учитывающих «$ min», либо я не могу передать отдел в offer_departement ...

Мой самый актуальный подход до того, как я решил обратиться за помощью:

db.prices.aggregate ([
        {
            $match : {
                offer : {
                    $ne : "0",
                },
                request : {
                    $ne : "0",
                },
            }
        },
        {
            $group : {
                _id : {
                    type : '$type',
                    dep : '$departement',
                },
                offer : {
                    $min : '$offer',
                },
                request : {
                    $max : '$req',
                }
            }
        },
    ]);

Но, конечно, результаты далеки от того, к чему я стремлюсь, я попробовал десятки ответов, в том числе от SO,но я не понимаю.

Буду очень признателен за помощь!

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

1 Ответ

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

Вместо $min и $max здесь вместо этого нужно сделать $sort сначала ввод, а затем использовать $first и $last аккумуляторы для границ группировки:

db.prices.aggregate([
  { "$match": { "offer": { "$gt": 0 } , "req": { "$gt": 0 } } },
  { "$sort": { "type": 1, "offer": 1, "req": 1 } },
  { "$group": {
    "_id": "$type",
    "offer_departement": { "$first": "$departement" },
    "offer": { "$first": "$offer" },
    "req_departement": { "$last": "$departement" },
    "req": { "$last": "$req" }
  }},
  { "$sort": { "req": 1 } }
])

Возвращает:

{
        "_id" : "FLAT_1",
        "offer_departement" : "D_TG",
        "offer" : 422,
        "req_departement" : "C_TG",
        "req" : 595
}
{
        "_id" : "FLAT_4",
        "offer_departement" : "F_TG",
        "offer" : 600,
        "req_departement" : "C_TG",
        "req" : 599
}
{
        "_id" : "FLAT_7",
        "offer_departement" : "D_TG",
        "offer" : 600,
        "req_departement" : "C_TG",
        "req" : 889
}

Также немного лучше "Использование индексаразумно "использовать $gt вместо $ne, поскольку" неравенство "не может эффективно использовать индекс, в котором может использоваться" диапазон "(даже открытый).Так что, если эти значения никогда не бывают отрицательными, тогда это будет лучший подход.

Обратите также внимание, что $group не имеет определенного порядка вывода, поэтому, если вы ожидаете определенного порядка, топрименять $sort после $group.

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