MongoDB Агрегирование коллекции ManytoMany с использованием mon goose, получение значений из разных коллекций - PullRequest
0 голосов
/ 19 марта 2020

У меня есть 3 коллекции в моем mongoDB

  1. Пользователь (имя, адрес и т. Д. c)
  2. Задача (имя, значок, уполномоченный)
  3. UserTask (User.ObjectId, Task.ObjectId, дата)

Коллекция пользователей:

{
    "users": [
        {
            "name": "Bill",
            "phone": "345"
        },
        {
            "name": "Steve",
            "phone": "123"
        },
        {
            "name": "Elon",
            "phone": "567"
        }
    ]
}

Коллекция задач, например:

{
    "tasks": [
        {
            "name": "Run 100m",
            "icon": "run"
        },
        {
            "name": "Walk 1 hour",
            "icon": "walk"
        },
        {
            "name": "Jog 30 minutes",
            "icon": "jog"
        }
    ]
}

UserTasks:

{
    "_id": "5e72fec..",
    "user": "5e72fa4..",
    "task": "5e72fbac..",
    "date": "2020-03-03T05:10:10.000Z",
    "createdAt": "2020-03-19T05:10:37.027Z",
    "updatedAt": "2020-03-19T05:10:37.027Z",
    "__v": 0
},
{
    "_id": "5e72fed3..",
    "user": "5e72fa4e..",
    "task": "5e72fbac..",
    "date": "2020-03-12T05:10:10.000Z",
    "createdAt": "2020-03-19T05:10:43.296Z",
    "updatedAt": "2020-03-19T05:10:43.296Z",
    "__v": 0
},
{
    "_id": "5e72fed6..",
    "user": "5e72fa..",
    "task": "5e72fb..",
    "date": "2020-03-15T05:10:10.000Z",
    "createdAt": "2020-03-19T05:10:46.057Z",
    "updatedAt": "2020-03-19T05:10:46.057Z",
    "__v": 0
},
{
    "_id": "5e72feda...",
    "user": "5e72fa4..",
    "task": "5e72fb..",
    "date": "2020-03-07T05:10:10.000Z",
    "createdAt": "2020-03-19T05:10:50.785Z",
    "updatedAt": "2020-03-19T05:10:50.785Z",
    "__v": 0
},

пользователь и задача содержат идентификатор объекта в коллекции пользовательских задач. Я хочу получить ответ от пользовательских задач, как показано ниже:

{
    "userTasks": [
      {
        "name": "Walk",
        "icon": "style",
        "assignee": "Steve",
        "log": [
          {
            "name": "Bill",
            "date": "2018-03-15"
          },
          {
            "name": "Elon",
            "date": "2018-02-27"
          },
          {
            "name": "Steve",
            "date": "2018-01-02"
          }
        ]
      },
      {
        "name": "Run",
        "icon": "running",
        "assignee": "Elon",
        "log": [
          {
            "name": "Bill",
            "date": "2019-03-12"
          },
          {
            "name": "Steve",
            "date": "2018-03-03"
          },
          {
            "name": "Elon",
            "date": "2018-03-01"
          }
        ]
      }
    ]
  }

Как мне этого добиться? Это лучший подход в Mongodb? Я привык к реляционной базе данных (SQL et c)

1 Ответ

1 голос
/ 19 марта 2020
  1. Как получить этот результат?
db.collection.aggregate([
    {
        $lookup: {
            from: "tasks",
            localField: "task",
            foreignField: "_id",
            as: "matchedTask"
        }
    },
    {
        $unwind: "$matchedTask"
    },
    {
        $lookup: {
            from: "users",
            localField: "user",
            foreignField: "_id",
            as: "matchedUser"
        }
    },
    {
        $unwind: "$matchedUser" //can there be tasks with no users? if so we need to tweak this.
    },
    {
        $group: {
            _id: "$matchedTask._id",
            name: {$first: "$matchedTask.name"},
            icon: {$first: "$matchedTask.icon"},
            assignee: "???", // what is this field suppose to be?
            log: {
                $push: {
                    name: "$matchedUser.name",
                    date: "$date"
                }
            }

        }
    }
])
Это лучший подход для пн go?

Определенно нет, пн go не любит объединять данные, это не построен, чтобы работать как реляционная база данных. $lookup даже не существовало в первые годы пн go.

В пн go дублирование данных не является грязным словом, на самом деле это рекомендуется.

Если вы хочу повышения производительности (и более простого кода), я рекомендую вам просто объединить эти 3 коллекции в одну.

** Имейте в виду, это мое мнение, я уверен, что вы встретите 50 других людей, говорящих 50 других вещей .

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