0.55.0 • Published 3 months ago

mongo2crate v0.55.0

Weekly downloads
-
License
ISC
Repository
github
Last release
3 months ago

Mongo to Crate

Sync MongoDB to Crate

import { default as Redis } from 'ioredis'
import _ from 'lodash/fp.js'
import { crate, initSync } from 'mongo2crate'
import { MongoClient } from 'mongodb'
import retry from 'p-retry'

const client = await MongoClient.connect()
const db = client.db()

/**
 * Use `mapper` to limit the length of strings since there is a 32k
 * character limit for text fields with the default columnar index.
 */
const mapper = (node: Node) => {
  if (typeof node.val === 'string') {
    return node.val.slice(0, 250)
  }
  return node.val
}

const sync = initSync(
    new Redis({ keyPrefix: 'cratedb:' }),
    db.collection('myCollection'),
    crate(),
    { omit: ['password', 'unneededStuff'], mapper }
)
// Log events
sync.emitter.on('process', console.info)
sync.emitter.on('error', console.error)
sync.emitter.on('cursorError', () => process.exit(1))
// Create SQL table from JSON schema
const schema = await sync.getCollectionSchema(db)
if (schema) {
    // The table name is derieved from the collection name and uses
    // the doc schema by default. These can be overriden in the options.
    await sync.createTableFromSchema(schema)
}
// Process change stream events
const changeStream = await sync.processChangeStream()
changeStream.start()
// Detect schema changes and stop change stream if detected
const schemaChange = await sync.detectSchemaChange(db)
schemaChange.start()
sync.emitter.on('schemaChange', changeStream.stop)
// Run initial scan of collection batching documents by 1000
const options = { batchSize: 1000 }
const initialScan = await sync.runInitialScan(options)
initialScan.start()

Convert a JSON schema to Crate DDL

The low-level function for converting a JSON schema to a table definition is convertSchema. You can also use the createTableFromSchema method on initSync to generate the table definition and write it to CrateDB.

import { convertSchema } from 'mongo2crate'

const schema = {
    bsonType: 'object',
    additionalProperties: false,
    required: ['name', 'type'],
    properties: {
        _id: {
            bsonType: 'objectId',
        },
        name: { bsonType: ['string', 'null'] },
        numberOfEmployees: {
            bsonType: 'string',
            enum: [
                '1 - 5',
                '6 - 20',
                '21 - 50',
                '51 - 200',
                '201 - 500',
                '500+',
            ],
        },
        notificationPreferences: {
            bsonType: 'array',
            items: {
                bsonType: 'string',
                enum: [
                    'newMatchingRFQ',
                    'activityOnRFQWhereParticipant',
                    'activityOnRFQBySameOrgUsers',
                ],
            },
        },
        addresses: {
            bsonType: 'array',
            items: {
                bsonType: 'object',
                additionalProperties: false,
                properties: {
                    address: {
                        bsonType: 'object',
                        additionalProperties: false,
                        properties: {
                            street: { bsonType: 'string' },
                            city: { bsonType: 'string' },
                            county: { bsonType: 'string' },
                            state: { bsonType: 'string' },
                            zip: { bsonType: 'string' },
                            country: { bsonType: 'string' },
                            latitude: { bsonType: 'number' },
                            longitude: { bsonType: 'number' },
                        },
                    },
                    name: { bsonType: 'string' },
                    isPrimary: { bsonType: 'bool' },
                },
            },
        },
        integrations: {
            bsonType: 'object',
            additionalProperties: true,
            properties: {
                stripe: {
                    bsonType: 'object',
                    additionalProperties: true,
                    properties: {
                        priceId: {
                            bsonType: 'number',
                        },
                        subscriptionStatus: {
                            bsonType: 'string',
                        },
                    },
                },
            },
        },
        metadata: {
            bsonType: 'object',
        },
    },
}

convertSchema(schema, '"doc"."foobar"', {
    strictMode: true,
    overrides: [
        // Glob expression
        { path: 'addresses.address.l*', bsonType: 'double' },
        {
            path: 'description',
            flags: ['notNull', 'indexOff', 'columnStoreOff'],
        },
    ],
})

Output:

CREATE TABLE IF NOT EXISTS "doc"."foobar" (
  "id" TEXT PRIMARY KEY,
  "name" TEXT,
  "description" TEXT NOT NULL INDEX OFF STORAGE WITH (columnstore = false),
  "numberOfEmployees" TEXT,
  "notificationPreferences" ARRAY (
    TEXT
  ),
  "addresses" ARRAY (
    OBJECT(STRICT) AS (
      "address" OBJECT(STRICT) AS (
        "street" TEXT,
        "city" TEXT,
        "county" TEXT,
        "state" TEXT,
        "zip" TEXT,
        "country" TEXT,
        "latitude" DOUBLE PRECISION,
        "longitude" DOUBLE PRECISION
      ),
      "name" TEXT,
      "isPrimary" BOOLEAN
    )
  ),
  "integrations" OBJECT(DYNAMIC) AS (
    "stripe" OBJECT(DYNAMIC) AS (
      "priceId" INTEGER,
      "subscriptionStatus" TEXT
    )
  ),
  "metadata" OBJECT(IGNORED)
)

Run the test locally

Create a .env file with the following variables set for your CrateDB cluster.

MONGO_CONN="mongodb+srv://..."
SQL_ENDPOINT='https://foo.bar:4200/_sql'
AUTH='username:password'

Then run npm test to run the tests.

0.55.0

3 months ago

0.53.0

7 months ago

0.54.0

5 months ago

0.52.0

8 months ago

0.51.0

8 months ago

0.50.0

8 months ago

0.49.0

8 months ago

0.47.0

9 months ago

0.46.0

10 months ago

0.44.0

11 months ago

0.45.0

11 months ago

0.43.0

2 years ago

0.41.0

2 years ago

0.42.0

2 years ago

0.42.1

2 years ago

0.38.0

2 years ago

0.36.0

2 years ago

0.40.0

2 years ago

0.39.0

2 years ago

0.37.0

2 years ago

0.35.1

2 years ago

0.35.0

2 years ago

0.34.0

2 years ago

0.33.0

2 years ago

0.32.0

2 years ago

0.31.0

2 years ago

0.30.0

2 years ago

0.29.0

2 years ago

0.28.0

2 years ago

0.27.1

2 years ago

0.27.0

2 years ago

0.26.0

2 years ago

0.25.0

2 years ago

0.24.0

2 years ago

0.23.1

2 years ago

0.23.0

2 years ago

0.21.0

3 years ago

0.20.0

3 years ago

0.21.2

3 years ago

0.22.0

2 years ago

0.21.1

3 years ago

0.10.0

3 years ago

0.19.0

3 years ago

0.11.0

3 years ago

0.9.0

3 years ago

0.12.0

3 years ago

0.8.0

3 years ago

0.13.0

3 years ago

0.14.0

3 years ago

0.13.1

3 years ago

0.9.1

3 years ago

0.15.0

3 years ago

0.13.2

3 years ago

0.5.0

3 years ago

0.16.0

3 years ago

0.4.0

3 years ago

0.17.0

3 years ago

0.7.0

3 years ago

0.18.0

3 years ago

0.6.0

3 years ago

0.3.0

3 years ago

0.2.0

3 years ago

0.1.0

3 years ago