Soy nuevo en Neo4j, así que me limité a recorrer algunos valores.
Tengo una lista de cadenas de habilidad a habilidad
let data = [ 'big_data, business_intelligence', 'big_data, data_collection', 'big_data, economic_growth', 'big_data, economy' ]Y quiero crear o actualizar la relación entre el lado izquierdo y el lado derecho
for (let item of data) { CreateSkillToSkillRelation(item); } const CreateSkillToSkillRelation = async (relation) => { let mainSkill = relation.split(",")[0]; let secundarySkill = relation.split(",")[1]; try { // Check if the relationship exists let { records } = await session.run( "MATCH(main:SKILL {name:$mainSkill}) -[relation:SKILL_TO_SKILL]-> (secundary:SKILL {name:$secundarySkill}) RETURN relation", { mainSkill, secundarySkill } ); let count = records[0]?._fields[0].properties.count > 0 ? records[0]._fields[0].properties.count + 1 : 1; // If count is greater then 1 then lets update the counter if (count > 1) { await session.run( "MATCH(main:SKILL {name:$mainSkill}) -[relation:SKILL_TO_SKILL]-> (secundary:SKILL {name:$secundarySkill}) SET relation.count = $count RETURN main, secundary", { mainSkill, secundarySkill, count, } ); } // Otherwise the skill relation is not created so lets create one else { await session.run( "CREATE(main:SKILL {name:$mainSkill}) -[:SKILL_TO_SKILL {count:$count}]-> (secundary:SKILL {name:$secundarySkill}) RETURN main, secundary", { mainSkill, secundarySkill, count, } ); } await session.close(); } catch (error) { console.log(error); } }; Pero cada vez que ejecuto esto, aparece el siguiente error Neo4jError: Queries cannot be run directly on a session with an open transaction; either run from within the transaction or use a different session.
¿Alguna idea de cómo puedo solucionar esto?
for (let item of data) { CreateSkillToSkillRelation(item); }No está esperando las promesas que crea, por lo que básicamente está tratando de ejecutar todas estas promesas al mismo tiempo en una única sesión que solo admite una única transacción simultánea.
Debe crear una sesión en cada llamada de CreateSkillToSkillRelation o esperar cada llamada usando una sola sesión.
Aunque tenga en cuenta que cierra la sesión al final de CreateSkillToSkillRelation pero solo si tiene éxito, le sugiero que mueva await session.close await session.close(); en un bloque finalmente.
La respuesta del colega @just_another_dotnet_dev es absolutamente correcta: ejecuta funciones asíncronas en un bucle y cierra la sesión en una de ellas.
El lenguaje de cifrado es muy rico y puede usarlo para hacer todo lo que intentó hacer con un bucle en Javascript. Algo como esto, usando UNWIND y MERGE :
const CreateSkillToSkillRelations = async (data) => { const session = driver.session(); try { let { records } = await session.run( `WITH split(row, ',') as rels WITH trim(rels[0]) as mainSkill, trim(rels[1]) as secundarySkill MERGE (main:SKILL {name: mainSkill}) -[relation:SKILL_TO_SKILL]-> (secundary:SKILL {name: secundarySkill}) ON CREATE SET relation.count = 1 ON MATCH SET relation.count = relation.count + 1 RETURN main, relation, secundary`, { data } ); } catch (error) { console.log(error); } finally { await session.close() } };