Ticket: Migration - Could anyone help identify where I'm going wrong?

Hi everyone, I’m having trouble completing Chapter 3: Admin Backend Ticket: Migration.
Running npm test -t migration, the console returns the failure below:

-------------------------start of console message-------------------- –
Determining test suites to run…Setup Mongo Connection
(node:10301) [MONGODB DRIVER] Warning: Top-level use of w, wtimeout, j, and fsync is deprecated. Use writeConcern instead.
(Use node --trace-warnings ... to show where the warning was created)
FAIL test/migration.test.js
migration
✕ migration (55 ms)

● Migration › migration

expect(received).not.toBeNull()

Received: null

  12 | lastupdated: { $type: "date" },
  13 | })
> 14 | expect(movie).not.toBeNull()
     | ^
  15 | })
  16 | })
  17 |

  at _callee2$ (test/migration.test.js:14:23)
  at tryCatch(node_modules/regenerator-runtime/runtime.js:63:40)
  at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:294:22)
  at Generator.next (node_modules/regenerator-runtime/runtime.js:119:21)
  at asyncGeneratorStep (node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:24)
  at _next (node_modules/@babel/runtime/helpers/asyncToGenerator.js:25:9)

Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 2,835 s
Ran all test suites matching /migration/i.
Teardown Mongo Connection

-------------------------end of console message--------------------

My code in the movie-last-updated-migration.js file is written as follows.

----------beginning of movie-last-updated-migration.js file ------------
require(“dotenv”).config({path: “./.env”});
const MongoClient = require(“mongodb”).MongoClient;
const ObjectId = require(“mongodb”).ObjectId;
const MongoError = require(“mongodb”).MongoError;

;(async() => {
try {
const host = process.env.MFLIX_DB_URI;
const client = await MongoClient.connect(
host,
{ useNewUrlParser: true },
)
const mflix = client.db(“mflix”)

    const predicate = { lastupdated: { $type: "string" } }
    //copied from discussion
    const projection = { lastupdated: 1 }
    const cursor = await mflix
        .collection("movies")
        .find(predicate, projection)
        .toArray()
    const moviesToMigrate = cursor.map(({ _id, lastupdated }) => ({
        updateOne: {
            filter: { _id: ObjectId(_id) },
            update: {
                $set: { lastupdated: Date.parse(lastupdated) },
            },
        },
    }));
    console.log(
        "\x1b[32m",
        `Found ${moviesToMigrate.length} documents to update`,
    )

    const { modifiedCount } = await mflix.collection("movies")
    .bulkWrite(moviesToMigrate);

    console.log("\x1b[32m", `${modifiedCount} documents updated`)
    client.close()
    process.exit(0)
} catch (e) {
    if (
        and instanceof MongoError &&
        e.message.slice(0, "Invalid Operation".length) === "Invalid Operation"
    ) {
        console.log("\x1b[32m", "No documents to update")
    } else {
        console.error("\x1b[31m", `Error during migration, ${e}`)
    }
    process.exit(1)
}

})()
-------------end of file movie-last-updated-migration.js ------------

If you look at the Date.parse documentation you will see that the result is not a Date.

So basically, your code is migrating a string field to a number field. But it should be a date.

If I remember correctly the code was supplied as

$set: { lastupdated: new Date(Date.parse(lastupdated)) },

rather than

Was it?

Hi steevej, thanks for your help.
I made the change and the error remains the same.
I think it must be somewhere else in the code that we can’t see.

Well, if you ran the migration once with the wrong $set your data set does not contains string lastupdated but may be number lastupdated.

This means that the predicate will not find any document to update.

I see 2 ways to get out of there:

  1. filter for $type:number rather than $type:string.
  2. or load a fresh data set
1 Like

Hi steevej, again, thanks for the help.
It made me rethink the whole process and I found the problem.
For some reason the connection to the .ENV file was not bringing up the data lookup information. I changed the movie-last-updated-migration.js file by putting the connection data directly in the host field and it worked.

2 Likes