在我的项目中,我正在尝试在标签Subjects
和Attributes
之间建立关系。
我按如下方式设置了相应的关系:
MATCH (a:Attribute { aid: {params}.aid } )
WITH a
MATCH (s:Subject { sid: {params}.sid } )
WITH a, s
MERGE (s)-[w:WEIGHTED {wid: {params}.wid }]->(a)
SET w = {params}
问题是,在执行此操作后,并非所有关系都已形成。而且,在我的情况下,应该有52个关系,但最初我只能到达39个地方(它变化)。当我再次调用该函数时,所有52个关系都已解决。
为什么会这样?
一些背景信息:
在设置关系之前,我首先创建节点主题和属性。但是,我只在neo4j服务器解决(使用promises)完成此任务后继续创建实际关系。即主题和属性应该已经填入数据库。
我使用GrapheneDB来托管我的neo4j服务器。
我分离任务的原因,首先创建标签然后创建关系是因为我有多个动态参数(id' s)。
但是,在我可以进行查询以创建关系之前可能有一段延迟?
或者还有别的吗?
我该如何解决这个问题?
HELP!
承诺
非常普遍地说,这是我应用承诺的方式,Queries
一个带有密码脚本的数组(它们是正确的)和Params
带有相应的参数。
查询1:科目
function querySubjects() {
var QueriesAll = []; // array of strings
var ParamsAll = []; // array of objects
for (var i=0; i<sidArray.length; i++) {
// [subjects]
var sid = sidArray[i];
var sparams = {};
sparams['sid'] = sid;
// merge subjects
var queryStr = " \
MERGE (s:Subject { sid: {sparams}.sid } ) \
SET s = {sparams} \
";
// [+]
QueriesAll.push(queryStr);
ParamsAll.push({
sparams: sparams
});
} // end s++
// --> loop queries
loopQueries(QueriesAll, ParamsAll).then(
function(success){
// -->
queryAttributes();
},
function(error){
// ...
}
);
}
查询2:属性
function queryAttributes() {
var QueriesAll = []; // array of strings
var ParamsAll = []; // array of objects
// -----------------------------------------------------------------
// init attributes
var aidArray = [];
for (var i=0; i<sidArray.length; i++) {
var sid = sidArray[i]; // array of keys
var attributes = subjects[sid]; // object of attributes
var attributesArray = Object.keys(attributes);
for (var j=0; j<attributesArray.length; j++) {
var aid = attributesArray[j];
aidArray.push(aid);
} // end a++
} // end s++
// filter out duplicates (works fine)
aidArray = aidArray.filter(onlyUnique);
// -----------------------------------------------------------------
// create queries
for (var j=0; j<aidArray.length; j++) {
// [attributes]
var aparams = {};
aparams['aid'] = aidArray[j];
// merge attribute
var queryStr = " \
MERGE (a:Attribute { aid: {aparams}.aid } ) \
SET a = {aparams} \
";
// [+]
QueriesAll.push(queryStr);
ParamsAll.push({
aparams: aparams
});
} // end a++
// --> loop queries
loopQueries(QueriesAll, ParamsAll).then(
function(success){
// -->
queryWeights();
},
function(error){
// ...
}
);
}
查询3:权重(此处发生问题)
function queryWeights() {
var QueriesAll = []; // array of strings
var ParamsAll = []; // array of objects
for (var i=0; i<sidArray.length; i++) {
// [subjects]
var sid = sidArray[i];
var sparams = {};
sparams['sid'] = sid;
// [attributes]
var attributes = subjects[sid];
var attributesArray = Object.keys(attributes);
for (var j=0; j<attributesArray.length; j++) {
// ...
var aid = attributesArray[j];
var aweight = attributes[aid];
var aparams = {};
var wparams = {};
// [weights]
aparams['aid'] = aid;
wparams['wid'] = sid + '-' + aid;
wparams['aweight'] = aweight;
// merge relationship subject-->attribute
var queryStr = " \
MATCH (a:Attribute{ aid: {aparams}.aid } ) \
WITH a \
MATCH (s:Subject { sid: {sparams}.sid } ) \
WITH a, s \
MERGE (s)-[w:WEIGHTED {wid: {wparams}.wid }]->(a) \
SET w = {wparams} \
RETURN a,s \
";
// [+]
QueriesAll.push(queryStr);
ParamsAll.push({
sparams: sparams,
aparams: aparams,
wparams: wparams
});
} // end a++
} // end s++
// --> loop queries
loopQueries(QueriesAll, ParamsAll).then(
function(success){
// <--
console.log('success')
},
function(error){
// ...
}
);
}
,其中
function loopQueries(Queries, Params) {
var promises = {};
for (var i=0; i<Queries.length; i++) {
var queryStr = Queries[i];
var params = Params[i];
var promise = queryNeo(queryStr, params);
promises[i] = promise;//promise;
};
return Q.all(promises);
}
function queryNeo(queryStr, params) {
var qq = Q.defer();
db.cypher({
query: queryStr,
params: params,
}, function (error, results) {
if (error) {
qq.reject(error)
} else {
qq.resolve(results)
}
});
return qq.promise;
}
延迟测试
我在创建关系之前等了几秒钟进行了测试。事实上,当我加入延迟时,它会立即生效。我不明白为什么我的查询返回它已完成,而事实并非如此。如何解决这个延迟问题,以便我知道它真的完成了?
答案 0 :(得分:2)
我不知道这是否会解决您的问题,但您的代码不必要地复杂。至少,简化它应该使它更容易理解和调试。
无需创建包含相同Cypher查询字符串的数组,因此无需使用Q.all()
。您可以使用UNWIND
调整每个Cypher查询,以便单个查询调用将一次处理每个传入的paramsAll
项。
我没有测试过代码的以下修改版本,但它至少应该让您了解如何简化代码。 1}}功能不再需要。
loopQueries