我是 neo4j 的新手(上周在 4.0.0 neo4j-DB 上使用 neo4j-Desktop 1.2.4),今天我开始使用 node.js 中的 neo4j-javascript-driver(4.0.1 版)。我浏览了用于 javascript 的 neo4j-driver 文档和用于驱动程序的官方 neo4j 文档,但没有发现会话状态的任何线索。
最小代码文件“Neo4jDB.js”为:
var Promise = require("bluebird");
const cfg = require('../config/config_all');
var neo4j = require('neo4j-driver');
var driver = neo4j.driver(
cfg.neo4j.uri,
neo4j.auth.basic(cfg.neo4j.user,cfg.neo4j.password),
{ maxTransactionRetryTime: 30000}
);
function Neo4jDB() { // NJDBxx
this.cleanUp = function() {
var session = driver.session();
session.close();
driver.close();
}
function error2msg(msgid,error,msgclass) {
if (typeof error.msgid === 'string' || typeof msgid === 'undefined' ) {
return error;
}
if (typeof msgclass === 'undefined') {
msgclass = 'DatabaseError';
}
return {
msgid : msgid,
msg : error,
msgclass : msgclass,
}
}
function pt_createAuthor(txc,author) {
return new Promise(function(resolve,reject){
if (typeof author !== 'object' || typeof author.name !== 'string') {
reject(error2msg('NJAT01','ParameterError in Author creation',"ParameterError"));
return;
}
txc.run("MERGE (a:Author { name:$nameParam }) "
+"RETURN a.name AS name",
{nameParam: author.name})
.then(authors => {
resolve(authors);
}).catch(error => {
console.log("p_createAuthor-error:",error);
txc.rollback();
reject(error2msg('NJAT02',error));
});
});
}
function pt_createBook(txc,book) {
return new Promise(function(resolve,reject){
if (typeof book !== 'object' || typeof book.title !== 'string' || typeof book.isbn !== 'string') {
reject(error2msg('NJBO01','ParameterError in Book creation',"ParameterError"));
return;
}
txc.run("MERGE (b:Book { title: $titleParam,isbn:$isbnParam }) "
+"RETURN b.title AS title,b.isbn AS isbn",
{titleParam: book.title,isbnParam : book.isbn})
.then(books => {
resolve(books);
}).catch(error => {
console.log("pt_createBook-error:",error);
reject(error2msg('NJBO02',error));
})
});
}
function pt_relateBookAndAuthor(txc,authorname,isbn) {
return new Promise(function(resolve,reject){
if (typeof authorname !== 'string' || typeof isbn !== 'string') {
reject(error2msg('NJBO03','ParameterError in Book relation to Author', "ParameterError"));
return;
}
txc.run("MATCH (a:Author),(b:Book) WHERE a.name = $authorParam AND b.isbn = $isbnParam "
+"CREATE (b)-[r:isAuthor]->(a) RETURN type(r) ",
{authorParam: authorname,isbnParam : isbn})
.then(rel => {
resolve(rel);
}).catch(error => {
console.log("pt_relateBookAndAuthor-error:",error);
reject(error2msg('NJBO02',error));
})
});
}
this.createBookAndAuthor = function(book,author) {
var session,txc;
return new Promise(function(resolve,reject){
if (typeof book !== 'object' || typeof book.title !== 'string' || typeof book.isbn !== 'string') {
reject(error2msg('NJBO03','ParameterError in Book creation',"ParameterError"));
return;
}
if (typeof author !== 'object' || typeof author.name !== 'string') {
reject(error2msg('NJAT03','ParameterError in Author creation',"ParameterError"));
return;
}
session = driver.session({database:'',defaultAccessMode: neo4j.session.WRITE});
txc = session.beginTransaction();
pt_createBook(txc,book)
.then(function(result){
console.log('result-1');
return pt_createAuthor(txc,author);
},function(error){
txc.rollback();
session.close();
reject(error2msg(undefined,error));
}).then(function(result){
if (typeof result === 'undefined') {
return;
}
console.log('result-2');
return pt_relateBookAndAuthor(txc,author.name,book.isbn);
},function(error){
txc.rollback();
session.close();
reject(error2msg(undefined,error));
})
.then(function(result){
if (typeof result === 'undefined') {
return;
}
console.log('result-3');
txc.commit()
.then( () => console.log("commit success"))
.catch( (error) => console.log("commit failed: ",error));
session.close();
resolve(book);
},function(error){
txc.rollback();
session.close();
reject(error2msg(undefined,error));
});
});
}
};
module.exports = new Neo4jDB();
我正在使用三个离散的例程pt_createAuthor
, pt_createAuthor
, pt_relateBookAndAuthor
. 尽管对整个任务使用了一个密码语句,但我已将事务拆分为这 3 个和其他基本功能,以便我可以将它们以与createBookAndAuthor
-Routine 中使用的类似模式组合在一起,也可以在其他舒适例程中使用(一个会话一笔交易,多项基本功能)。
目前我在规范文件中使用了一些具体的示例数据:
const pdb = require('./Neo4jDB');
const assert = require('assert');
describe('Neo4jDB',function(){
describe('First Book',function(){
var author1 = {
name:'Boris Grundl'
};
var author2 = {
name:'Bodo Schäfer'
}
var book1 = {
title: 'Leading simple',
subtitle: 'Führen kann so einfach sein',
isbn: '978-3-89749-708-5',
}
it('create pook with 1st author',function(done) {
pdb.createBookAndAuthor(book1,author1)
.then(function(result){
// console.log(result);
done();
},function(error){
console.log(error);
done(error);
})
})
it('merge book with 2nd author',function(done) {
pdb.createBookAndAuthor(book1,author2)
.then(function(result){
// console.log(result);
done();
},function(error){
console.log(error);
done(error);
})
})
it('cleans up',function(done){
pdb.cleanUp();
done();
})
}) // Connection tests.
}); // Neo4jDB