Home > Enterprise >  How do I migrate my data from one structure to another?
How do I migrate my data from one structure to another?

Time:02-02

I have a MongoDB with 3 collections. Here are the 3 collections each with an example of a document it contains:

tag

_id: ObjectId('61b873ec6d075801f7a97e18')
name: 'TestTag'
category: 'A'

computer

_id: ObjectId('6098c5ab615d9e23543d0f6f')
name: 'TestComputer'
category: 'A',
tags: [
    ObjectId('61b873ec6d075801f7a97e18')
]

setting

_id: ObjectId('61e56339b528bf009feca149')
name: 'TestSetting'
category: 'A',
tags: [
    ObjectId('61b873ec6d075801f7a97e18')
]

As you can see all 3 documents have a category property and the last 2 documents have a tags property. The idea is that you can create a tag and tag your computers and settings with the tag, but only within the same category.

Now I'm trying to go from tags to groups, so instead of tagging computers and settings, I have created a new group collection that looks like this:

groups

_id: ObjectId('63d2929c2c71e51f8ffcc921')
name: 'TestGroup'
category: 'A'
computers: []
settings: []

I want to "migrate" from tags to groups. So for each tag in my tags collection, I want to create a group with the same name and same category. For each computer and setting that is tagged with that tag, I want to add their _id to the computers and settings arrays in the group.

So if we take the documents I've shown, it would create the following group:

_id: ObjectId('63d26d582c71e51f8ffcc8aa')
name: 'TestTag'
category: 'A'
computers: [
    ObjectId('6098c5ab615d9e23543d0f6f')
]
settings: [
    ObjectId('61e56339b528bf009feca149')
]

How do I make a query that does this?

CodePudding user response:

First perform $group to group all tags by category and name. Then, $lookup to computer and setting to find matching records. Finally, wrangle the $lookup results a bit and $merge/$out to groups collection.

db.tag.aggregate([
  {
    $group: {
      _id: {
        name: "$name",
        category: "$category"
      },
      tags: {
        "$addToSet": "$_id"
      }
    }
  },
  {
    "$lookup": {
      "from": "computer",
      "localField": "tags",
      "foreignField": "tags",
      "let": {
        c: "$_id.category"
      },
      "pipeline": [
        {
          $match: {
            $expr: {
              $eq: [
                "$$c",
                "$category"
              ]
            }
          }
        },
        {
          $project: {
            "_id": 1
          }
        }
      ],
      "as": "computers"
    }
  },
  {
    "$lookup": {
      "from": "setting",
      "localField": "tags",
      "foreignField": "tags",
      "let": {
        c: "$_id.category"
      },
      "pipeline": [
        {
          $match: {
            $expr: {
              $eq: [
                "$$c",
                "$category"
              ]
            }
          }
        },
        {
          $project: {
            "_id": 1
          }
        }
      ],
      "as": "settings"
    }
  },
  {
    $project: {
      _id: 0,
      name: "$_id.name",
      category: "$_id.category",
      computers: {
        "$map": {
          "input": "$computers",
          "as": "c",
          "in": "$$c._id"
        }
      },
      settings: {
        "$map": {
          "input": "$settings",
          "as": "s",
          "in": "$$s._id"
        }
      }
    }
  },
  {
    "$merge": {
      "into": "groups",
      "on": "_id",
      "whenMatched": "merge"
    }
  }
])

Mongo Playground

  • Related