Группировка по возрасту на основе даты - PullRequest
0 голосов
/ 22 ноября 2018

У меня есть структура:

[
            {
                "_id": {
                    "question": "Voluptatem perferendis voluptas ex.",
                    "option": "Eligendi ratione fuga autem fugiat velit quo.",
                    "user_dob": {
                        "$date": {
                            "$numberLong": "1306281600000"
                        }
                    }
                },
                "total_votes": 1
            },
            {
                "_id": {
                    "question": "Voluptatem perferendis voluptas ex.",
                    "option": "Eligendi ratione fuga autem fugiat velit quo.",
                    "user_dob": {
                        "$date": {
                            "$numberLong": "22118400000"
                        }
                    }
                },
                "total_votes": 1
            }, {...}, ...
]

Мне нужно сгруппировать данные по user_age_group.У меня есть предопределенная возрастная группа:

'age_groups' => [
        '0-14 years' => ['from' => 0, 'to' => 14],
        '15-24 years' => ['from' => 15, 'to' => 24],
        '25-54 years' => ['from' => 25, 'to' => 54],
        '55-64 years' => ['from' => 55, 'to' => 64],
        '65 years and over' => ['from' => 65, 'to' => 999]
    ]

Или даже, скажем, у меня есть уже рассчитанные переменные $ from и $ to date для всех этих возрастных групп.

В конце концов мне нужно получить следующую структуру:

[
            {
                "_id": "Voluptatem perferendis voluptas ex.",
                "options": [
                    {
                        "option": "Vero rerum qui animi quia assumenda.",
                        "votes_by_age": [
                            {
                                "age_group": "25-54 years",
                                "total_votes": 1
                            },
                            {
                                "age_group": "55-64 years",
                                "total_votes": 1
                            },
                            {
                                "age_group": "65 years and over",
                                "total_votes": 5
                            }
                        ]
                    }, {...}, ...
]

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

1 Ответ

0 голосов
/ 22 ноября 2018

Вы выполняете перевод здесь, используя оператор $switch, сравнивая текущую дату с $year от сохраненной даты.

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

db.collection.aggregate([
  { "$group": {
    "_id": {
      "question": "$_id.question",
      "option": "$_id.option",
      "age_group": {
        "$let": {
          "vars": { 
            "age": {
              "$subtract": [
                { "$year": new Date() },
                { "$year": "$_id.user_dob" }
              ]
            }
          },
          "in": {
            "$switch": {
              "branches": [
                {
                  "case": { "$lte": [ "$$age", 14 ] },
                  "then": "0-14 years",
                },
                {
                  "case": { "$lte": [ "$$age", 24 ] },
                  "then": "15-24 years",
                },
                {
                  "case": { "$lte": [ "$$age", 54 ] },
                  "then": "25-54 years",
                },
                {
                  "case": { "$lte": [ "$$age", 64 ] },
                  "then": "55-64 years",
                }
              ],
              "default": "65 years and over"
            }
          }
        }
      }
    },
    "total_votes": { "$sum": "$total_votes" }
  }},
  { "$group": {
    "_id": {
      "question": "$_id.question",
      "option": "$_id.option"
    },
    "votes_by_age": {
      "$push": {
        "age_group": "$_id.age_group",
        "total_votes": "$total_votes"
      }
    },
    "total_votes": { "$sum": "$total_votes" }
  }},
  { "$group": {
    "_id": "$_id.question",
    "options": {
      "$push": {
        "option": "$_id.option",
        "votes_by_age": "$votes_by_age",
        "total_votes": "$total_votes"
      }
    },
    "total_votes": { "$sum": "$total_votes" }
  }}
])

Что выводит из предоставленных данных:

{
        "_id" : "Voluptatem perferendis voluptas ex.",
        "options" : [
                {
                        "option" : "Eligendi ratione fuga autem fugiat velit quo.",
                        "votes_by_age" : [
                                {
                                        "age_group" : "25-54 years",
                                        "total_votes" : 1
                                },
                                {
                                        "age_group" : "0-14 years",
                                        "total_votes" : 1
                                }
                        ],
                        "total_votes" : 2
                }
        ],
        "total_votes" : 2
}

Обратите внимание, что появляется часть вопросасодержать код PHP, поэтому вместо new Date() для оболочки на основе JavaScript это будет MongoDB\BSON\UTCDatetime(time() * 1000), с использованием PHP time() и функции драйвера MongoDB, чтобы обернуть его в качестве даты BSON.

$let означает, что вы не будете повторять одно и то же выражение каждый раз, когда на него ссылаются в случаях $switch."vars" объявляется и ссылается через префикс $$, как в "$$age", как показано.

Каждый $group постепенно удаляет часть ключа, поэтомунакапливается и затем перемещается в массив через $push при перемещении ключей.Дополнительные total_votes на каждом уровне должны прояснить, как работает это накопление

...