сначала группа, сделай второй бакетау в агрегации mongodb - PullRequest
0 голосов
/ 31 октября 2019

У меня есть набор данных, структурированный так:

 {
          "id": 1230239,
          "group_name": "A",
          "confidence": 0.14333882876354542,

  },
  {
          "id": 1230240,
          "group_name": "B",
          "confidence": 0.4434535,

   },

И т. Д.

Довольно просто вычислить группы и количество элементов в каждом сегменте уровня достоверности, используя $bucketautoвот так:

{
  "$bucketAuto": {
     "groupBy": "$confidence",
     "buckets": 4
 }
}

Но как я могу сделать то же самое для каждой группы, отдельно?

Я попробовал это:

    {"$group": {
                    "_id": "group",
                    "data": {
                        "$push": {
                            "confidence": "$confidence",
                        }
                    }
                }
                },
                {
                    "$bucketAuto": {
                        "groupBy": "$data.confidence",
                        "buckets": 4
                    }
                }

Но это не работает.

Что мне нужно примерно это в качестве вывода:

{ 'groupA': 
     {
            "_id": {
                "min": 0.0005225352581638143,
                "max": 0.2905137273072962
            },
            "count": 67
        },
        {"_id": {
                "min": 0.2905137273072962,
                "max":0.5531611756507283,
            },
            "count": 43
        },
}, 
{ 'groupB': 
     {
       "_id": {
                "min": 0.0005225352581638143,
                "max": 0.2905137273072962
            },
            "count": 67
        },
        {"_id": {
                "min": 0.2905137273072962,
                "max":0.5531611756507283,
            },
            "count": 43
        },
}

Любой совет или подсказка будет оценена

1 Ответ

1 голос
/ 01 ноября 2019

$facet на помощь - оператор "мультигруппы". Этот конвейер:

db.foo.aggregate([
{$facet: {
  "groupA": [
{$match: {"group_name": "A"}}
,{$bucketAuto: {
        "groupBy": "$confidence",
        "buckets": 3
    }}
           ]

  ,"groupB": [
{$match: {"group_name": "B"}}
,{$bucketAuto: {
        "groupBy": "$confidence",
        "buckets": 3
    }}
           ]

    }}
   ]);

выдает искомый вывод:

{
    "groupA" : [
        {
            "_id" : {
                "min" : 0.14333882876354542,
                "max" : 0.34333882876354543
            },
            "count" : 2
        },
        {
            "_id" : {
                "min" : 0.34333882876354543,
                "max" : 0.5433388287635454
            },
            "count" : 2
        },
        {
            "_id" : {
                "min" : 0.5433388287635454,
                "max" : 0.5433388287635454
            },
            "count" : 1
        }
    ],
    "groupB" : [
        {
            "_id" : {
                "min" : 0.5433388287635454,
                "max" : 0.7433388287635454
    // etc. etc. 

Если вы хотите работать полностью динамично, вам нужно сделать это за два прохода: сначала получите отчетливыйимена групп, затем создайте выражение $facet из этих имен:

db.foo.distinct("group_name").forEach(function(name) {
        fct_stage["group" + name] = [
                                     {$match: {"group_name": name}}
                                     ,{$bucketAuto: {
                                             "groupBy": "$confidence",
                                             "buckets": 3
                                         }}
                                     ];
    });

db.foo.aggregate([ {$facet: fct_stage} ]);

...