Javascript 使用node.js在neo4j中导入CSV
我正在尝试使用node.js将Javascript 使用node.js在neo4j中导入CSV,javascript,node.js,neo4j,Javascript,Node.js,Neo4j,我正在尝试使用node.js将csv文件导入neo4j。我必须将数据插入多个集合/表格,因此我必须使用node.js脚本插入数据。但我的问题是,在插入csv数据时无法防止数据重复 CSV数据示例: name ------------- Afghanistan Afghanistan Aland Albania Albania Bangladesh Bangladesh index.js cp = require('child_process'); child = cp.fork(__dirna
csv
文件导入neo4j
。我必须将数据插入多个集合/表格
,因此我必须使用node.js脚本插入数据。但我的问题是,在插入csv数据时无法防止数据重复
CSV数据示例:
name
-------------
Afghanistan
Afghanistan
Aland
Albania
Albania
Bangladesh
Bangladesh
index.js
cp = require('child_process');
child = cp.fork(__dirname + "/background-import-csv-file.js");
child.on('message', function(msg) {
console.log("background-insert-process said : ", msg);
});
file = path.resolve(__dirname, `./file/simplemaps.csv`);
child.send(file);
在后台导入csv文件.js
中,我用两种不同的方式编写代码
基于第一个承诺的(后台导入csv文件.js
):
/collection/country.js
:
Q = require('q');
Country = function Country(neo) {
this.country = "Country"; this.neo = neo;
};
Country.prototype.find = function find(filters) {
query = `MATCH (a:Country { name: '${filters.name}' } ) RETURN {country:properties(a)}`;
return this.neo.run(query, filters).then(resp => resp);
}
Country.prototype.create = function create(data) {
query = `CREATE (ax:Country { name: '${data.name}' } ) RETURN ax `;
return this.neo.run(query, {}).then(resp => resp[0].properties).catch(err => err)
}
Country.prototype.insert = function insert(country) {
filter = { name: country.name };
return Q(this.find(filter))
.then(resp => resp.length > 0 ? Q.resolve({ msg: `country: [${country.name}] is already exist` }) : Q.resolve(this.create(country)) )
.then(resp => resp)
.catch(e => Q.reject(e));
}
module.exports = Country;
EventEmitter = require('events').EventEmitter;
util = require('util');
Country = function Country(neo) {
this.neo = neo; EventEmitter.call(this);
};
util.inherits(Country, EventEmitter);
Country.prototype.find = function find(filters) {
query = `MATCH (a:Country { name: '${filters.name}' } ) RETURN {country:properties(a)}`;
return this.neo.run(query, {}).then(resp => this.emit('find', resp));
}
Country.prototype.create = function create(data) {
query = `CREATE (ax:Country { name: '${data.name}' } ) RETURN ax `;
return this.neo.run(query, {}).then(resp => this.emit('create', resp[0].properties)).catch(err => err)
}
/common/driver.js
neo4j = require('neo4j-driver').v1;
function DB() {
this.driver = neo4j.driver(); this.session = this.driver.session();
}
DB.prototype.run = function run(query, data) {
return this.session.run(query, data)
.then(response => response.records.map(
record => record._fields[0] ?
record._fields.length ? record._fields[0] : {} : {}
) ).catch(err => new Error(err) );
}
module.exports = DB;
当我在终端中运行index.js
时,在数据库中,我有2个阿富汗
,1个阿兰
,2个阿尔巴尼亚
和2个孟加拉国
。但我的数据库中需要1个阿富汗
、1个阿拉德
、1个阿尔巴尼亚
和1个孟加拉国
。当我分析代码时,发现在插入数据之前,我正在检查数据(Country.prototype.find=function find(filters)
)是否已经存在,但它总是返回空结果。这就是它插入多个数据的原因。若我再次运行index.js
,则不会将新数据插入数据库。为了解决这个问题,我尝试了以下CQL
:
MERGE (c:Country { name: '${data.name}' } ) RETURN c
它插入的是唯一的数据,但它占用了很多时间。然后我编写了以下代码:
事件驱动(后台导入csv文件.js
):
/collection/country.js
:
Q = require('q');
Country = function Country(neo) {
this.country = "Country"; this.neo = neo;
};
Country.prototype.find = function find(filters) {
query = `MATCH (a:Country { name: '${filters.name}' } ) RETURN {country:properties(a)}`;
return this.neo.run(query, filters).then(resp => resp);
}
Country.prototype.create = function create(data) {
query = `CREATE (ax:Country { name: '${data.name}' } ) RETURN ax `;
return this.neo.run(query, {}).then(resp => resp[0].properties).catch(err => err)
}
Country.prototype.insert = function insert(country) {
filter = { name: country.name };
return Q(this.find(filter))
.then(resp => resp.length > 0 ? Q.resolve({ msg: `country: [${country.name}] is already exist` }) : Q.resolve(this.create(country)) )
.then(resp => resp)
.catch(e => Q.reject(e));
}
module.exports = Country;
EventEmitter = require('events').EventEmitter;
util = require('util');
Country = function Country(neo) {
this.neo = neo; EventEmitter.call(this);
};
util.inherits(Country, EventEmitter);
Country.prototype.find = function find(filters) {
query = `MATCH (a:Country { name: '${filters.name}' } ) RETURN {country:properties(a)}`;
return this.neo.run(query, {}).then(resp => this.emit('find', resp));
}
Country.prototype.create = function create(data) {
query = `CREATE (ax:Country { name: '${data.name}' } ) RETURN ax `;
return this.neo.run(query, {}).then(resp => this.emit('create', resp[0].properties)).catch(err => err)
}
这一次,它显示了相同的结果。我错过了什么?任何建议都会很有帮助
注意:我使用
fastcvs
进行csv解析,使用Q
进行承诺 实际上,我可以想象以下解决方案:
对(c:Country)断言c.name创建约束是唯一的
上图。我的问题是,在
csv
文件解析中,它非常快(事件驱动),不需要等待就可以将数据插入数据库。因此,我必须暂停文件解析,然后恢复它
我使用以下代码解决问题:
基于承诺(后台导入csv文件.js):
cp = require('child_process');
csv = require('fast-csv');
Q = require('q');
DB = require("./common/driver");
Country = require('./collection/country');
process.on("message", (file) => {
stream = fs.createReadStream(file);
csvstream = csv
.fromStream(stream, { headers: true })
.on("data", function(data) {
csvstream.pause(); // pause the csv file parsing
countryData = { "name": data.name };
neo = new DB();
country = new Country(neo);
country.insert(countryData)
.then(resp => {
process.send(resp.msg);
neo.close();
return csvstream.resume(); // after completing db process, resume
})
.catch(err => {
process.send(err);
return csvstream.resume(); // if failed, then resume
});
})
.on("end", () => process.send("file read complete") );
});
“勒贝尔”是什么意思?我看不出一个明显的原因,为什么不能用一个简单的密码查询来实现这一点。