合并关系并不总是有效(延迟)
Merge relationship does not always work (delay)
在我的项目中,我试图在标签 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 服务器解决(使用承诺)完成此任务后才继续创建实际关系。 IE。数据库中应该已经填写了主题和属性。
我使用 GrapheneDB 来托管我的 neo4j 服务器。
我之所以将任务分开,首先创建标签然后创建关系,是因为我有多个动态参数 (id)。
但在我进行查询以创建关系之前可能会有延迟?
或者还有别的什么?
我该如何解决这个问题?
求助!
承诺
非常笼统地说,这就是我应用承诺的方式,因为 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;
}
延迟测试
我进行了测试并等待了几秒钟才创建关系。事实上,当我加入延迟时,它会立即起作用。但是我不明白为什么我的查询 returns 已经完成,但事实并非如此。如何解决这个延迟问题,让我知道它真的完成了?
我不知道这是否能解决您的问题,但您的代码不必要地复杂。至少,简化它应该更容易理解和调试。
无需创建包含相同 Cypher 查询字符串的数组,因此无需使用 Q.all()
。您可以使用 UNWIND
调整每个 Cypher 查询,以便单个查询调用可以处理每个传入的 paramsAll
项,一次一个。
我没有测试您代码的以下修改版本,但它至少应该让您了解如何简化事情。不再需要 loopQueries
函数。
function querySubjects() {
var query = " \
UNWIND {sparams} AS param
MERGE (s:Subject { sid: param.sid } ) \
SET s = param \
";
var paramsAll = []; // array of objects
for (var i=0; i<sidArray.length; i++) {
// [subjects]
var sid = sidArray[i];
var sparams = {};
sparams['sid'] = sid;
paramsAll.push({
sparams: sparams
});
} // end s++
// --> loop queries
queryNeo(query, paramsAll).then(
function(success){
// -->
queryAttributes();
},
function(error){
// ...
}
);
}
function queryAttributes() {
var query = " \
UNWIND {aparams} AS param
MERGE (a:Attribute { aid: param.aid } ) \
SET a = param \
";
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];
paramsAll.push({
aparams: aparams
});
} // end a++
// --> loop queries
queryNeo(query, paramsAll).then(
function(success){
// -->
queryWeights();
},
function(error){
// ...
}
);
}
function queryWeights() {
var query = " \
UNWIND {params} AS param
MATCH (a:Attribute{ aid: param.aid } ) \
MATCH (s:Subject { sid: param.sid } ) \
MERGE (s)-[w:WEIGHTED {wid: param.wparams.wid }]->(a) \
SET w = param.wparams \
RETURN a,s \
";
var paramsAll = []; // array of objects
for (var i=0; i<sidArray.length; i++) {
// [subjects]
var sid = sidArray[i];
// [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 wparams = {};
// [weights]
wparams['wid'] = sid + '-' + aid;
wparams['aweight'] = aweight;
paramsAll.push({
sid: sid
aid: aid,
wparams: wparams
});
} // end a++
} // end s++
// --> loop queries
queryNeo(query, paramsAll).then(
function(success){
// <--
console.log('success')
},
function(error){
// ...
}
);
}
在我的项目中,我试图在标签 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 服务器解决(使用承诺)完成此任务后才继续创建实际关系。 IE。数据库中应该已经填写了主题和属性。
我使用 GrapheneDB 来托管我的 neo4j 服务器。
我之所以将任务分开,首先创建标签然后创建关系,是因为我有多个动态参数 (id)。
但在我进行查询以创建关系之前可能会有延迟?
或者还有别的什么?
我该如何解决这个问题?
求助!
承诺
非常笼统地说,这就是我应用承诺的方式,因为 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;
}
延迟测试
我进行了测试并等待了几秒钟才创建关系。事实上,当我加入延迟时,它会立即起作用。但是我不明白为什么我的查询 returns 已经完成,但事实并非如此。如何解决这个延迟问题,让我知道它真的完成了?
我不知道这是否能解决您的问题,但您的代码不必要地复杂。至少,简化它应该更容易理解和调试。
无需创建包含相同 Cypher 查询字符串的数组,因此无需使用 Q.all()
。您可以使用 UNWIND
调整每个 Cypher 查询,以便单个查询调用可以处理每个传入的 paramsAll
项,一次一个。
我没有测试您代码的以下修改版本,但它至少应该让您了解如何简化事情。不再需要 loopQueries
函数。
function querySubjects() {
var query = " \
UNWIND {sparams} AS param
MERGE (s:Subject { sid: param.sid } ) \
SET s = param \
";
var paramsAll = []; // array of objects
for (var i=0; i<sidArray.length; i++) {
// [subjects]
var sid = sidArray[i];
var sparams = {};
sparams['sid'] = sid;
paramsAll.push({
sparams: sparams
});
} // end s++
// --> loop queries
queryNeo(query, paramsAll).then(
function(success){
// -->
queryAttributes();
},
function(error){
// ...
}
);
}
function queryAttributes() {
var query = " \
UNWIND {aparams} AS param
MERGE (a:Attribute { aid: param.aid } ) \
SET a = param \
";
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];
paramsAll.push({
aparams: aparams
});
} // end a++
// --> loop queries
queryNeo(query, paramsAll).then(
function(success){
// -->
queryWeights();
},
function(error){
// ...
}
);
}
function queryWeights() {
var query = " \
UNWIND {params} AS param
MATCH (a:Attribute{ aid: param.aid } ) \
MATCH (s:Subject { sid: param.sid } ) \
MERGE (s)-[w:WEIGHTED {wid: param.wparams.wid }]->(a) \
SET w = param.wparams \
RETURN a,s \
";
var paramsAll = []; // array of objects
for (var i=0; i<sidArray.length; i++) {
// [subjects]
var sid = sidArray[i];
// [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 wparams = {};
// [weights]
wparams['wid'] = sid + '-' + aid;
wparams['aweight'] = aweight;
paramsAll.push({
sid: sid
aid: aid,
wparams: wparams
});
} // end a++
} // end s++
// --> loop queries
queryNeo(query, paramsAll).then(
function(success){
// <--
console.log('success')
},
function(error){
// ...
}
);
}