Published on

เรียนรู้การใช้งาน migrate-mongo

เรียนรู้การใช้งาน migrate-mongo
เรียนรู้การใช้งาน migrate-mongo

สวัสดีคุณผู้อ่านทุกท่านจร้า วันนี้เจมส์จะมาเขียนบทความเกี่ยวกับการใช้งาน migrate-mongo ครับ เราจะใช้ตอนที่ต้องการ migrate database คือมีข้อมูลเก่าอยู่แล้ว และอยากเพิ่ม หรือแก้ไข field ใน collection นั้นๆ หรือเพิ่ม collection ใหม่ขึ้นมาโดยดูข้อมูลจากอีก collection นึง เป็นต้น

อธิบายอาจจะไม่ค่อยเห็นภาพเท่าไร เรามาลองทำกันเลยดีกว่าครับจะได้เห็นภาพมากขึ้น

มาเริ่มกันเลย

ติดตั้ง migrate-mongo

เปิด Terminal และพิมพ์คำสั่ง

npm install -g migrate-mongo

หลังจากติดตั้งเรียบร้อย ให้เราลองใช้คำสั่ง

migrate-mongo --version

ถ้าหากไม่มีอะไรผิดพลาด จะแสดง version ที่เราติดตั้งขึ้นมา

Clone Project ตัวอย่าง

ในขั้นตอนนี้สำหรับคนที่ต้องการทำตามเน้อครับ เจมส์เตรียมโปรเจคที่มี MongoDB ไว้ให้เรียบร้อยแล้ว โดยเราจะ Clone Project นี้ลงมาแล้วก็สั่งให้คำสั่งให้ restore ข้อมูลใส่ใน MongoDB เตรียมไว้ก่อน

สามารถเข้าไป clone ได้ที่นี่เลยครับ example-mongo-restore หรือจะใช้คำสั่ง

git clone git@github.com:jame3032002/example-mongo-restore.git

จากนั้นให้ เข้าไปใน project โดยใช้คำสั่ง

cd example-mongo-restore

จากนั้นให้ใช้คำสั่ง

docker-compose up

เมื่อ run เรียบร้อยแล้ว ให้เปิดอีก Terminal ขึ้นมาครับ เข้ามาที่ root project เดิมที่เรา clone ลงมา จากนั้นให้ใช้คำสั่ง

sh restore.sh

ในที่นี้เจมส์เขียน script ไว้ใน คำสั่ง restore.sh ไว้แล้ว โดยคำสั่งที่เขียนไว้คือให้ restore ข้อมูลใส่ใน db ที่เราสร้าง

เราสามารถลองใช้ robo 3T connect เข้าไปดูว่ามีข้อมูลอะไรบ้าง ซึ่งหากคุณผู้อ่าน clone แล้วทำตามคำอธิบายข้างต้นโดยไม่ได้เปลี่ยนค่าอะไร

  • username ที่ใช้ connect MongoDB คือ kajame
  • password ที่ใช้ connect MongoDB คือ 111111
  • database ที่ใช้ connect MongoDB คือ example

ดูในจากไฟล์ docker-compose.yaml ในโปรเจคที่เจมส์เตรียมไว้ให้

ตัวอย่างการใช้ robo3T connect ไปที่ MongoDB
ตัวอย่างการใช้ robo3T connect ไปที่ MongoDB
ทดสอบการเชื่อมต่อ DB โดยใช้ username และ password ที่ระบุก่อนหน้า
ทดสอบการเชื่อมต่อ DB โดยใช้ username และ password ที่ระบุก่อนหน้า
ตัวอย่างข้อมูลที่มีอยู่ใน DB example
ตัวอย่างข้อมูลที่มีอยู่ใน DB example

ในตอนนี้เรามีข้อมูลเรียบร้อยแล้ว เราจะมาลอง migrate ข้อมูลเพิ่มเข้าไปกันครับ โดยเจมส์จะขออ้างอิงจากข้อมูลในตัวอย่างของเจมส์นะครับ

มาลอง Migrate ข้อมูลกัน

ขั้นแรกให้เราเข้าไปใน project ของเรา ในที่นี่เดี๋ยวเจมส์จะเข้าไปใน project ที่ใช้เป็นตัวอย่างข้างต้นนะครับ จากนั้นให้เราสร้าง directory ชื่อที่เราต้องการให้เก็บข้อมูลใส่ไว้ในนั้น ในที่นี้เจมส์จะสร้างว่า database-migrations และเข้าไปใน directory ที่สร้าง

mkdir database-migrations
cd database-migrations

จากนั้นให้ใช้คำสั่ง

migrate-mongo init

หลังจากที่ใช้คำสั่ง migrate-mongo init จะพบว่ามีไฟล์ migrate-mongo-config.js และ directory ชื่อ migrations ถูกสร้างขึ้นมา

ในไฟล์ migrate-mongo-config.js จะเป็นการตั้งค่าต่าง ๆ ซึ่งในตอนนี้เราจะสนใจแค่ในส่วน url ก่อนครับ

  • ตั้งค่า url โดยเราจะเปลี่ยนเป็น mongodb://kajame:111111@localhost:27017/example

ซึ่งในส่วนของการตั้งค่าของ migrate-mongo-config.js ให้เหลือแค่นี้ได้เลยครับ

migrate-mongo-config.js
// In this file you can configure migrate-mongo

const config = {
  mongodb: {
    url: "mongodb://kajame:111111@localhost:27017/example",
  },

  // The migrations dir, can be an relative or absolute path. Only edit this when really necessary.
  migrationsDir: "migrations",

  // The mongodb collection where the applied changes are stored. Only edit this when really necessary.
  changelogCollectionName: "changelog",

  // The file extension to create migrations and search for in migration dir
  migrationFileExtension: ".js",

  // Enable the algorithm to create a checksum of the file contents and use that in the comparison to determine
  // if the file should be run.  Requires that scripts are coded to be run multiple times.
  useFileHash: false,

  // Don't change this, unless you know what you're doing
  moduleSystem: "commonjs",
};

module.exports = config;

จากนั้นเราจะมาสร้าง migration script กันครับ

สร้างไฟล์ migration script

ให้เราเปิด Terminal และเข้าไปใน directory database-migrations ที่เราสร้างก่อนหน้านี้ จากนั้นให้ใช้คำสั่ง

migrate-mongo create add_user_collection_from_tweet_collection

ซึ่งมีรูปแบบคือ

migrate-mongo create [คำอธิบาย]

เมื่อใช้คำสั่งสร้าง migration script แล้วจะพบว่ามีไฟล์หนึ่งไฟล์ถูกสร้างมาใน directory migrations

ไฟล์ของเจมส์ที่ถูกสร้างมาชื่อ 20231126111354-add_user_collection_from_tweet_collection.js

ของคุณผู้อ่านชื่อไฟล์ที่ได้อาจจะแตกต่างกันกับเจมส์นะครับ ไม่ต้องตกใจ

ซึ่งส่วนนี้คือส่วนที่เราจะมาเขียน script สำหรับ migrate mongo กันครับ

method ชื่อ up เราจะเขียน script ที่สำหรับใช้ migrate

method ชื่อ down เราจะเขียน script ที่ใช้สำหรับ rollback กลับ (กรณีที่เพิ่มไปแล้ว แล้วเกิดปัญหา)

ตัวอย่างโจทย์ที่ได้รับมาคือ บริษัทต้องการเพิ่ม collection users โดยดูจาก user.id ใน collection tweets ซึ่งต้องการแค่ field id, name ใน collection user เท่านั้น

เราจะสามารถเขียนไฟล์เพื่อ migrate ได้ดังนี้ครับ

20231126111354-add_user_collection_from_tweet_collection.js
module.exports = {
  async up(db, client) {
    console.log("=== start add user from tweets collection ===");
    const tweets = await db.collection("tweets").find({}).toArray();

    for (const [index, tweet] of tweets.entries()) {
      const { user } = tweet;

      const u = await db.collection("users").findOne({ id: user.id });

      if (!u) {
        await db.collection("users").insertOne({ id: user.id, name: user.name });
      }

      console.log(`Migrate Completed ${index}/${tweets.length}`);
    }

    console.log("=== end add user from tweets collection ===");
  },

  async down(db, client) {
    db.collection("users").deleteMany({});
  },
};

จากโค้ดในส่วน up คือเราจะให้มันดึงข้อมูลจาก collection tweets จากนั้น เอาผลลัพธ์ที่ได้โดยเอาข้อมูล user.id ที่ได้ มาหาใน collection users ถ้าหากว่าไม่มีข้อมูลใน collection user ก็เพิ่มข้อมูล user คนนั้นเข้าไป

จากโค้ดในส่วน down คือ เราจะลบ collection users ออกไป

จากนั้นให้ใช้คำสั่ง

migrate-mongo up

เมื่อเราเข้าไปดูใน robo3T จะพบว่ามี collection ชื่อ changelog เพิ่มขึ้นมา ส่วนนี้จะเป็น log เก็บไว้ว่าเรา migrate อันไหนไปแล้วบ้าง

และจะพบว่ามี collection ชื่อ users ขึ้นมา ซึ่ง collection users ที่เพิ่มขึ้นมานั้นก็มาจาก script ที่เราเขียนไว้ในก่อนหน้านี้นี่เองครับ

ตัวอย่างข้อมูล changelog ที่ถูกเพิ่มเข้ามา
ตัวอย่างข้อมูล changelog ที่ถูกเพิ่มเข้ามา
ตัวอย่างข้อมูล user ที่ถูกเพิ่มเข้ามา
ตัวอย่างข้อมูล user ที่ถูกเพิ่มเข้ามา

หากคุณผู้อ่านพบว่า เราอาจจะ migrate ผิด สามารถใช้คำสั่ง

migrate-mongo down

เพื่อ rollback ได้ แต่! คำสั่งใน method down ที่เราเขียนต้องถูกต้องด้วยนะครับ ไม่งั้นก็ยิ่งเละไปใหญ่ ^^

ถ้าใช้ migrate-mongo down มันคือการ rollback กลับไป step ก่อนหน้าเท่านั้นนะครับ

หวังว่าบทความนี้จะมีประโยชน์กับคุณผู้อ่านทุกท่านเน้อครับ หากมีส่วนไหนผิดพลาดประการใด ก็ขออภัยมา ณ ที่นี้ด้วยเน้อครับ หรือหากคุณผู้อ่านมีส่วนไหนต้องการแนะนำเพิ่มเติม ก็สามารถพิมพ์ไว้ใน comment ได้เลยเน้อครับ