Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit 0b0a677

Browse files
Merge pull request #41 from topcoder-platform/migration-script
Script to migrate data from db to es
2 parents 303496a + 838c501 commit 0b0a677

File tree

2 files changed

+159
-1
lines changed

2 files changed

+159
-1
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
"start": "node app.js",
88
"lint": "standard \"**/*.js\"",
99
"insert-data": "node scripts/db/genData.js",
10-
"delete-data": "node scripts/db/dropAll.js"
10+
"delete-data": "node scripts/db/dropAll.js",
11+
"migrate-db-to-es": "node scripts/db/dumpDbToEs.js"
1112
},
1213
"repository": {
1314
"type": "git",

scripts/db/dumpDbToEs.js

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
const _ = require('lodash')
2+
const models = require('../../src/models')
3+
const logger = require('../../src/common/logger')
4+
const { getESClient } = require('../../src/common/es-client')
5+
const {
6+
topResources,
7+
userResources,
8+
organizationResources,
9+
modelToESIndexMapping
10+
} = require('../constants')
11+
12+
async function cleanupES () {
13+
const client = getESClient()
14+
client.indices.delete({
15+
index: '_all'
16+
}, function (err, res) {
17+
if (err) {
18+
console.error(err.message)
19+
} else {
20+
console.log('Existing indices have been deleted!')
21+
}
22+
})
23+
}
24+
25+
async function insertIntoES (modelName, body) {
26+
const esResourceName = modelToESIndexMapping[modelName]
27+
28+
if (!esResourceName) {
29+
logger.error(`Cannot insert data into model ${modelName}. No equivalent elasticsearch index found`)
30+
31+
return
32+
}
33+
34+
const client = getESClient()
35+
36+
if (_.includes(_.keys(topResources), esResourceName)) {
37+
await client.create({
38+
index: topResources[esResourceName].index,
39+
type: topResources[esResourceName].type,
40+
id: body.id,
41+
body,
42+
refresh: 'true'
43+
})
44+
} else if (_.includes(_.keys(userResources), esResourceName)) {
45+
const userResource = userResources[esResourceName]
46+
47+
const user = await client.getSource({
48+
index: topResources.user.index,
49+
type: topResources.user.type,
50+
id: body.userId
51+
})
52+
53+
if (userResource.nested === true && userResource.mappingCreated !== true) {
54+
await client.indices.putMapping({
55+
index: topResources.user.index,
56+
type: topResources.user.type,
57+
include_type_name: true,
58+
body: {
59+
properties: {
60+
[userResource.propertyName]: {
61+
type: 'nested'
62+
}
63+
}
64+
}
65+
})
66+
userResource.mappingCreated = true
67+
}
68+
69+
const relateId = body[userResource.relateKey]
70+
71+
if (!user[userResource.propertyName]) {
72+
user[userResource.propertyName] = []
73+
}
74+
75+
if (_.some(user[userResource.propertyName], [userResource.relateKey, relateId])) {
76+
logger.error(`Can't create existing ${esResourceName} with the ${userResource.relateKey}: ${relateId}, userId: ${body.userId}`)
77+
} else {
78+
user[userResource.propertyName].push(body)
79+
await client.update({
80+
index: topResources.user.index,
81+
type: topResources.user.type,
82+
id: body.userId,
83+
body: { doc: user },
84+
refresh: 'true'
85+
})
86+
}
87+
} else if (_.includes(_.keys(organizationResources), esResourceName)) {
88+
const orgResource = organizationResources[esResourceName]
89+
90+
const organization = await client.getSource({
91+
index: topResources.organization.index,
92+
type: topResources.organization.type,
93+
id: body.organizationId
94+
})
95+
96+
const relateId = body[orgResource.relateKey]
97+
98+
if (!organization[orgResource.propertyName]) {
99+
organization[orgResource.propertyName] = []
100+
}
101+
102+
if (_.some(organization[orgResource.propertyName], [orgResource.relateKey, relateId])) {
103+
logger.error(`Can't create existing ${esResourceName} with the ${orgResource.relateKey}: ${relateId}, organizationId: ${body.organizationId}`)
104+
} else {
105+
organization[orgResource.propertyName].push(body)
106+
await client.update({
107+
index: topResources.organization.index,
108+
type: topResources.organization.type,
109+
id: body.organizationId,
110+
body: { doc: organization },
111+
refresh: 'true'
112+
})
113+
}
114+
}
115+
}
116+
117+
/**
118+
* import test data
119+
* @return {Promise<void>}
120+
*/
121+
async function main () {
122+
let keys = Object.keys(models)
123+
keys = _.orderBy(keys, k => {
124+
const esResourceName = modelToESIndexMapping[k]
125+
126+
// Create parent data first
127+
if (_.includes(_.keys(topResources), esResourceName)) {
128+
return -1
129+
}
130+
131+
return 1
132+
})
133+
134+
await cleanupES()
135+
136+
for (let i = 0; i < keys.length; i++) {
137+
const key = keys[i]
138+
if (models[key].tableName) {
139+
try {
140+
const data = await models.DBHelper.find(models[key], [])
141+
for (let i = 0; i < data.length; i++) {
142+
await insertIntoES(key, data[i])
143+
}
144+
logger.info('import data for ' + key + ' done')
145+
} catch (e) {
146+
logger.error(e)
147+
logger.warn('import data for ' + key + ' failed')
148+
}
149+
}
150+
}
151+
logger.info('all done')
152+
process.exit(0)
153+
}
154+
155+
(async () => {
156+
main().catch(err => console.error(err))
157+
})()

0 commit comments

Comments
 (0)