Skip to content

Instantly share code, notes, and snippets.

@gegedenice
Last active July 20, 2023 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gegedenice/c7e53cc4c3d65b8bc1639d4b55a90be6 to your computer and use it in GitHub Desktop.
Save gegedenice/c7e53cc4c3d65b8bc1639d4b55a90be6 to your computer and use it in GitHub Desktop.
Sudoc-PS/CR PACA Nice/Neo4j dataviz

Documentation pour la création du graphe de données Neo4j de l'application SudocPS pro du CR PACA/Nice (réseau Sudoc-PS) : chargement des données des unicas Sudoc et des périodiques de presse locale ancienne (BnF).

Lien vers l'app en prod

Fichiers joints :

  • ark_presselocale-extrait.csv [unused] : exemple de fichier obtenu avec la fonctionnalité d'export csv du site http://presselocaleancienne.bnf.fr/accueil
  • ppn_unicas-extrait.csv : exemple de fichier de ppn unicas attendu exporté manuellement depuis l'espace Self Service Sudoc
We can make this file beautiful and searchable if this error is corrected: No commas found in this CSV file in line 0.
dpt;ark
06;ark:/12148/cb450269951
06;ark:/12148/cb44394783t
06;ark:/12148/cb43853753j
06;ark:/12148/cb438537228
06;ark:/12148/cb43849119z
83;ark:/12148/cb328868846
83;ark:/12148/cb32886880t
83;ark:/12148/cb32886879m
83;ark:/12148/cb32884946f
98;ark:/12148/cb328876857

Graphgist pour le Sudoc-PS (données dynamiques à partir web services Sudoc et SRU BnF)

Modèle de données

neo4j metadata

Supprimer le graphe (tous les noeuds et toutes les relations)

MATCH (n) DETACH DELETE n

Contraintes d’unicité des nodes

Ces contraintes permettent d’assurer l’intégrité de la BDD lors de la construction du graphe. A saisir une par une dans Neo4j

CREATE CONSTRAINT ON (s:SudocUnica) ASSERT s.ppn IS UNIQUE
CREATE CONSTRAINT ON (s:SudocNotUnica) ASSERT s.ppn IS UNIQUE
CREATE CONSTRAINT ON (b:BnfPresselocale) ASSERT b.ark IS UNIQUE
CREATE CONSTRAINT ON (b:Bib) ASSERT b.rcr IS UNIQUE
CREATE CONSTRAINT ON (d:Dpt) ASSERT d.number IS UNIQUE

Les noeuds Départements

Note
à personnaliser selon les départements couverts par votre ILN
CREATE
 (:Dpt {name:"Alpes-Maritimes",number:"06"}),
 (:Dpt {name:"Var",number:"83"}),
 (:Dpt {name:"Monaco",number:"99"})

Les données du Sudoc

Les bibliothèques

  • Les noeuds Bibliothèques à partir du web service Iln2rcr

Note
remplacer avec votre numéro ILN dans l’url du web service iln2rcr
WITH "https://www.idref.fr/services/iln2rcr/230" AS url
call apoc.load.xml(url,"/sudoc/query/result") yield value as libs  UNWIND libs._children as bib WITH [attr IN bib._children WHERE attr._type IN ['rcr','shortname','latitude','longitude'] | attr._text] as data
CREATE (:Bib {rcr:data[0],name:data[1],latitude:data[2],longitude:data[3]})
  • Les liens entre bibliothèques et départements où elles se situent

MATCH (b:Bib),(d:Dpt) WHERE b.rcr STARTS WITH d.number CREATE (b)-[r:LOCATED]->(d)

Les unicas

  • Les noeuds Unicas à partir du fichier ppn_unicas.csv

Note
fichier à exporter manuellement depuis Abes Stp pour votre ILN, et à déposer au format csv dans <NEO4J_HOME>/import. Si besoin, modifier le nom du fichier dans la requête.
LOAD CSV WITH HEADERS FROM
'file:///ppn_unicas-all.csv'
AS line FIELDTERMINATOR ';' UNWIND line.ppn as ppn CREATE (s:SudocUnica {ppn:ppn})
  • Les propriétés des noeuds issus des champs des notices en Unimarc

MATCH (s:SudocUnica) UNWIND s.ppn as ppn call apoc.load.xml("https://www.sudoc.fr/"+ppn+".xml",null,{failOnError:false}) yield value as record
UNWIND record._children as fields
WITH s,fields,[attr IN fields._children WHERE attr.code IN ['a'] | attr._text] as data WHERE fields.tag IN ["011","200","309"] CALL apoc.create.setProperty(s, CASE fields.tag
 WHEN "011" THEN "issn"
 WHEN "200" THEN "titre"
 WHEN "309" THEN "controle"
END, data[0]) YIELD node return node
  • Ajout des zones 606 en propriétés

MATCH (s:SudocUnica) UNWIND s.ppn as ppn call apoc.load.xml("https://www.sudoc.fr/"+ppn+".xml",null,{failOnError:false}) yield value as record
UNWIND record._children as fields
WITH s,fields,[attr IN fields._children WHERE attr.code IN ['a'] | attr._text] as data WHERE fields.tag IN ["606"] CALL apoc.create.setProperty(s, "indexation", collect(data[0])) YIELD node return node

Les relations Unicas-bibliothèques

  • Les liens entre les noeuds Unicas et chaque bibliothèque qui les possèdent à partir du Web service multiwhere

MATCH (s:SudocUnica) UNWIND s.ppn as ppn call apoc.load.xml("https://www.sudoc.fr/services/multiwhere/"+ppn,"/sudoc/query/result/library/rcr",{failOnError:false}) yield value as item MATCH (b:Bib {rcr:item._text}) CREATE (s)-[:OWNED_BY]->(b)
  • On repasse sur les notices en Unimarc XML du Sudoc pour ajouter l’état de collection (champ 955$r) comme une propriété de la relation entre unicas et bibliothèques

MATCH (s:SudocUnica)-[rel:OWNED_BY]-(b) UNWIND s.ppn as ppn call apoc.load.xml("https://www.sudoc.fr/"+ppn+".xml",null,{failOnError:false}) yield value as record
UNWIND record._children as fields WITH rel,fields,[attr IN fields._children WHERE attr.code = 'r'| attr._text] as data WHERE fields.tag = "955" SET rel.etat_de_collection=data[0]

Les données de la BnF

Source de données : 2 sources possibles

[Manuel|Non utilisé] Export csv à partit du catalogue de la BnF

On constitue un fichier ark_presselocale.csv qui contient le numéro des départements de référence et les arks.

Requête qui créent les noeuds Presselocale et les liens avec les noeuds Départements

LOAD CSV WITH HEADERS FROM
'file:///ark_presselocale-all.csv'
AS line FIELDTERMINATOR ';' MATCH (d:Dpt) WHERE d.number=line.dpt CREATE (b:Bnfrecord {source:"presselocale",ark:line.ark})-[rel:IS_ABOUT]->(d)

[Documentation|Utilisé en prod] Extraction des identifiants ark par scrapping du site presselocalancienne.bnf.fr

On utilise les urls "parlantes" du site lorsqu’on fait une recherche, en jouant sur les paramètres de l’url &territoire, &page et &taille.

  • requête Cypher qui parse cette page du département 83 pour extraire les 565 id ark

CALL apoc.load.html("http://presselocaleancienne.bnf.fr/cherche?&av=true&equRech1=mot&mot1=&typeRechCritere1=all&relation=et&equRech2=mot&mot2=&typeRechCritere2=all&type=tout&territoire=d83&siecle=&annee=&anneeFac=&page=1&taille=600",{a:"a"}) YIELD value UNWIND value.a as record WITH record WHERE record.attributes.href CONTAINS "/ark:/" return record.attributes.href
  • ou alors en une seule requête pour les 3 départements

Note
avec une petite subtilité pour la Principauté de Monaco qui a le numéro 99 dans le Sudoc (1ers chiffres des RCR des bibs monégasques) mais 98 dans la répartition territoriale de la BnF
UNWIND ["06","83","98"] as dep CALL apoc.load.html("http://presselocaleancienne.bnf.fr/cherche?&av=true&equRech1=mot&mot1=&typeRechCritere1=all&relation=et&equRech2=mot&mot2=&typeRechCritere2=all&type=tout&territoire=d"+dep+"&siecle=&annee=&anneeFac=&page=1&taille=10",{a:"a"}) YIELD value UNWIND value.a as record WITH CASE dep WHEN "06" THEN "06" WHEN "83" THEN "83" WHEN "98" THEN "99" END as dpt,record WHERE record.attributes.href CONTAINS "/ark:/" return dpt,record.attributes.href
  • Donc, requête qui créent les noeuds BnfPresselocale et les liens avec les noeuds Départements avec cette méthode

UNWIND ["06","83","98"] as dep CALL apoc.load.html("http://presselocaleancienne.bnf.fr/cherche?&av=true&equRech1=mot&mot1=&typeRechCritere1=all&relation=et&equRech2=mot&mot2=&typeRechCritere2=all&type=tout&territoire=d"+dep+"&siecle=&annee=&anneeFac=&page=1&taille=1000",{a:"a"}) YIELD value UNWIND value.a as record WITH CASE dep WHEN "06" THEN "06" WHEN "83" THEN "83" WHEN "98" THEN "99" END as dpt,record MATCH (d:Dpt) WHERE d.number=dpt WITH d,record WHERE record.attributes.href CONTAINS "/ark:/" MERGE (b:BnfPresselocale {ark:record.attributes.href})-[rel:IS_ABOUT]->(d)

[Utilisé en prod|partir de là pour les requêtes] Extraction des identifiants ark par scrapping du site presselocalancienne.bnf.fr

Mais le paramètre de taille (nb de résultats max) dans l’url ne peut pas dépasser 1000, il faudrait donc introduire un 4ème paramètre de pagination pour le 06…​bref en attendant de caler le truc, on spécifie les requêtes département par département A saisir une par une dans Neo4j

CALL apoc.load.html("http://presselocaleancienne.bnf.fr/cherche?&av=true&equRech1=mot&mot1=&typeRechCritere1=all&relation=et&equRech2=mot&mot2=&typeRechCritere2=all&type=tout&territoire=d06&siecle=&annee=&anneeFac=&page=1&taille=1000&nombrePages=2",{a:"a"}) YIELD value UNWIND value.a as record WITH record MATCH (d:Dpt) WHERE d.number="06" WITH d,record WHERE record.attributes.href CONTAINS "/ark:/" MATCH (d) MERGE (b:BnfPresselocale {ark:record.attributes.href}) MERGE (b)-[rel:IS_ABOUT]->(d)

CALL apoc.load.html("http://presselocaleancienne.bnf.fr/cherche?&av=true&equRech1=mot&mot1=&typeRechCritere1=all&relation=et&equRech2=mot&mot2=&typeRechCritere2=all&type=tout&territoire=d06&siecle=&annee=&anneeFac=&page=2&taille=1000&nombrePages=2",{a:"a"}) YIELD value UNWIND value.a as record WITH record MATCH (d:Dpt) WHERE d.number="06" WITH d,record WHERE record.attributes.href CONTAINS "/ark:/" MATCH (d) MERGE (b:BnfPresselocale {ark:record.attributes.href}) MERGE (b)-[rel:IS_ABOUT]->(d)

CALL apoc.load.html("http://presselocaleancienne.bnf.fr/cherche?&av=true&equRech1=mot&mot1=&typeRechCritere1=all&relation=et&equRech2=mot&mot2=&typeRechCritere2=all&type=tout&territoire=d83&siecle=&annee=&anneeFac=&page=1&taille=1000",{a:"a"}) YIELD value UNWIND value.a as record WITH record MATCH (d:Dpt) WHERE d.number="83" WITH d,record WHERE record.attributes.href CONTAINS "/ark:/" MATCH (d) MERGE (b:BnfPresselocale {ark:record.attributes.href}) MERGE (b)-[rel:IS_ABOUT]->(d)

CALL apoc.load.html("http://presselocaleancienne.bnf.fr/cherche?&av=true&equRech1=mot&mot1=&typeRechCritere1=all&relation=et&equRech2=mot&mot2=&typeRechCritere2=all&type=tout&territoire=d98&siecle=&annee=&anneeFac=&page=1&taille=1000",{a:"a"}) YIELD value UNWIND value.a as record WITH record MATCH (d:Dpt) WHERE d.number="99" WITH d,record WHERE record.attributes.href CONTAINS "/ark:/" MATCH (d) MERGE (b:BnfPresselocale {ark:record.attributes.href}) MERGE (b)-[rel:IS_ABOUT]->(d)
  • [inutile avec contraintes d’unicité] Détection des doublons et dédoublonnage

//trouver les doublons
MATCH (b1:BnfPresselocale),(b2:BnfPresselocale) WHERE b1.ark = b2.ark and id(b1) < id(b2) return b1,b2
//merger les noeuds doublons
MATCH (b:BnfPresselocale) WITH b.ark as ark, COLLECT(b) AS ns WHERE size(ns) > 1 CALL apoc.refactor.mergeNodes(ns) YIELD node
RETURN node
//vérifier que le dédoublonnage est effectif et que les liens ont bien été préservés
MATCH (b:BnfPresselocale)-[i:IS_ABOUT]->(d:Dpt) WITH b,count(i) as rel_cnt WHERE rel_cnt > 1 RETURN b

les noeuds BnfPresselocale

Les propriétés (titre-ISSN-édition(lieu & date)) des noeuds issus des champs des notices en Unimarc à partir de l’API SRU du catalogue de la BnF.

MATCH (b:BnfPresselocale) UNWIND b.ark as ark call apoc.load.xml("http://catalogue.bnf.fr/api/SRU?version=1.2&operation=searchRetrieve&query=bib.persistentid%20adj%20%22"+replace(ark,'/ark:/','ark:/')+"%22&recordSchema=unimarcxchange",null,{failOnError:false}) yield value as record UNWIND record._children[3]._children[0]._children[2]._children[0]._children as fields WITH b,fields,[attr IN fields._children WHERE attr.code IN ['a','d'] | attr._text] as data WHERE fields.tag IN ["011","200","210"] CALL apoc.create.setProperty(b, CASE fields.tag
 WHEN "011" THEN "issn"
 WHEN "200" THEN "titre"
 WHEN "210" THEN "edition"
END, apoc.text.join(data, '|')) YIELD node return node

Vérification

De manière un peu inexpliquée, certaines données issues du SRU peuvent ne pas être implémentées dans le graphe. Il faut requêter le graphe pour isoler les noeuds BnfPresseLocale n’ayant que l’id ark, puis refaire tourner l’interrogation du SRU sur ces ark

MATCH (p:BnfPresselocale) WHERE not exists(p.titre) return p

Former un array avec les id ark puis (par ex) :

["/ark:/12148/cb328684845","/ark:/12148/cb32706843s","/ark:/12148/cb32708522g","/ark:/12148/cb32763300n","/ark:/12148/cb32764100b","/ark:/12148/cb32682303p",
"/ark:/12148/cb32823671b","/ark:/12148/cb328529361","/ark:/12148/cb41317167k","/ark:/12148/cb327967948","/ark:/12148/cb32877304c","/ark:/12148/cb32700481s",
"/ark:/12148/cb32891606v","/ark:/12148/cb32812859k","/ark:/12148/cb32837656m","/ark:/12148/cb328371567","/ark:/12148/cb32854745x","/ark:/12148/cb328479857",
"/ark:/12148/cb32762870z","/ark:/12148/cb328334710","/ark:/12148/cb41096915f","/ark:/12148/cb411052534","/ark:/12148/cb41096893z","/ark:/12148/cb32778861n",
"/ark:/12148/cb328315964","/ark:/12148/cb413055163","/ark:/12148/cb32793463f","/ark:/12148/cb41438417p"] as a  MATCH (b:BnfPresselocale) where b.ark = a call apoc.load.xml("http://catalogue.bnf.fr/api/SRU?version=1.2&operation=searchRetrieve&query=bib.persistentid%20adj%20%22"+replace(a,'/ark:/','ark:/')+"%22&recordSchema=unimarcxchange",null,{failOnError:false}) yield value as record UNWIND record._children[3]._children[0]._children[2]._children[0]._children as fields WITH b,fields,[attr IN fields._children WHERE attr.code IN ['a','d'] | attr._text] as data WHERE fields.tag IN ["011","200","210"] CALL apoc.create.setProperty(b, CASE fields.tag
 WHEN "011" THEN "issn"
 WHEN "200" THEN "titre"
 WHEN "210" THEN "edition"
END, apoc.text.join(data, '|')) YIELD node return node

Les relations Unicas-Presse locale

Appariement entre les noeuds SudocUnica et BnfPresselocale avec la cération d’une relation de type SAME_AS sur la base de l’équvalence des ISSN

MATCH (s:SudocUnica),(b:BnfPresselocale) WHERE EXISTS(s.issn) AND EXISTS(b.issn) AND s.issn=b.issn CREATE (s)-[:SAME_AS]->(b)

Enrichissement du graphe

Ajout d’un nouveau type de noeud Numerisation pour représenter les versions numérisées de la presse locale

  • Source : SRU BnF, champ 325 disponible depuis la version 2 du SRU

  • On repasse sur chaque noeud ayant le label BnfPresselocale et, s’il existe des versions numérisées, on créé des nouveaux noeuds avec un lien HAS_VERSION depuis le noeud de la notice imprimée.

MATCH (b:BnfPresselocale) UNWIND b.ark as ark
call apoc.load.xml("http://catalogue.bnf.fr/api/SRU?version=1.2&operation=searchRetrieve&query=bib.persistentid%20adj%20%22"+replace(ark,'/ark:/','ark:/')+"%22&recordSchema=unimarcxchange",null,{failOnError:false}) yield value as record UNWIND record._children[3]._children[0]._children[2]._children[0]._children as fields WITH b,fields,[attr IN fields._children WHERE attr.code IN ['d','u'] | attr._text] as data WHERE fields.tag IN ["325"]
CREATE (b)-[:HAS_VERSION]->(n:Numerisation {etab:data[1],url:data[0]})

Ajout d’un nouveau type de noeud SudocNotUnica

Pour les noeuds BnfPresselocale que l’on peut relier à notice correspondante dans le Sudoc mais qui ne sont pas des unicas.

  • [Non utilisé] Récupération des localisations Sudoc par scrapping de la page web de la notice sur le site.

Par exemple sur un identifiant ark précis

CALL apoc.load.html("http://presselocaleancienne.bnf.fr/ark:/12148/cb34546118d",{a:"a.lienExterne"}) YIELD value as record UNWIND record.a as rec return rec.attributes.href
  • Recours aux web services Sudoc

    • depuis les noeuds BnfPresselocale qui ont un ISSN et qui ne sont pas déjà liés à un noeud SudocUnica : récupération du ppn de la notice équivalente dans le Sudoc sur la base de l’ISSN grâce au web service issn2ppn et création de nouveaux noeuds ayant le label SudocNotUnica connectés aux noeuds de départ par une realtion SAME_AS

MATCH (b:BnfPresselocale) WHERE NOT (b)<-[:SAME_AS]-() AND EXISTS(b.issn) UNWIND b.issn as issn CALL apoc.load.xml("http://www.sudoc.fr/services/issn2ppn/"+issn,"/sudoc/query/result",{failOnError:false}) YIELD value
UNWIND value._children[0]._text AS ppn with b,ppn,issn MATCH (b) WHERE b.issn = issn MERGE (s:SudocNotUnica {issn:issn,ppn:ppn,titre:b.titre}) MERGE (s)-[r:SAME_AS]->(b)
  • localisations des nouveaux noeuds Sudoc hors unicas

     //hide
    //setup
    //output
    MATCH (bnf:BnfPresselocale)<-[:SAME_AS]-(s:SudocNotUnica) UNWIND s.ppn as ppn CALL apoc.load.xml("http://www.sudoc.fr/services/multiwhere/"+ppn,"/sudoc/query/result",{failOnError:false}) YIELD value AS value WITH s,value UNWIND value._children as lib MATCH (b:Bib) WHERE lib._children[0]._text = b.rcr CREATE (s)-[r:OWNED_BY]->(b)
  • Qualité des données sur noeuds SudocNotUnica : récupération de la zone 309 de la notice Sudoc

MATCH (s:SudocNotUnica) UNWIND s.ppn as ppn call apoc.load.xml("https://www.sudoc.fr/"+ppn+".xml",null,{failOnError:false}) yield value as record
UNWIND record._children as fields
WITH s,fields,[attr IN fields._children WHERE attr.code IN ['a'] | attr._text] as data WHERE fields.tag IN ["309"] CALL apoc.create.setProperty(s, CASE fields.tag
 WHEN "309" THEN "controle"
END, data[0]) YIELD node return node

Spécial visualisation

Pour aider à la compréhension visuelle du graphe dans l’application, on calcule le poids (la taille) des noeuds avec leur degré et on les regroupe par couleurs en fonction de leur type

  • Métriques de graphe : degré (nb de liens entrants et sortants)

Requête simple qui calcule le nombre de relations de chauqe noeud pour chaque label et ajoute un attribut degre

MATCH (n) SET n.degre=size( (n)-[]-() ) RETURN *
  • Communauté

Rien à voir ici avec les algos de détection de communauté, on attribue juste une valeur dans un attribut "type" en fonction du label des noeuds

MATCH (n:Dpt) SET n.type="Département" RETURN *
MATCH (n:Bib) SET n.type="Bibliothèque" RETURN *
MATCH (n:SudocUnica) SET n.type="Sudoc unica" RETURN *
MATCH (n:SudocNotUnica) SET n.type="Sudoc not unica" RETURN *
MATCH (n:BnfPresselocale) SET n.type="Presse locale ancienne" RETURN *
MATCH (n:Numerisation) SET n.type="Numérisation" RETURN *

Transfert du graphe local dans une sandbox Neo4j

  • Export du graphe en csv

CALL apoc.graph.fromDB('graph-prod', {}) YIELD graph
CALL apoc.export.csv.graph(
 graph,
 '../export/exportedSudocpsGraph.csv',
 null
 ) YIELD file, nodes, relationships
RETURN file, nodes, relationships
  • Déposer l’export csv dans un entrepôt atteignable par le protocole http/https (par exemple dans un repo Github accessible par raw)

  • Requête d’import dans la Sandbox

    • Noeuds

LOAD CSV WITH HEADERS FROM "https://raw.githubusercontent.com/gegedenice/divers-files/master/exportedSudocpsGraph.csv" AS line FIELDTERMINATOR ',' WITH line WHERE EXISTS(line._id) AND line._labels = ":Dpt" CREATE (p:Dpt {initId:line._id,number:line.number,name:line.name,type:line.type,degre:line.degre}) return p

LOAD CSV WITH HEADERS FROM "https://raw.githubusercontent.com/gegedenice/divers-files/master/exportedSudocpsGraph.csv" AS line FIELDTERMINATOR ',' WITH line WHERE EXISTS(line._id) AND line._labels = ":Bib" CREATE (p:Bib {initId:line._id,name:line.name,rcr:line.rcr,latitude:line.latitude,longitude:line.longitude,type:line.type,degre:line.degre}) return p

LOAD CSV WITH HEADERS FROM "https://raw.githubusercontent.com/gegedenice/divers-files/master/exportedSudocpsGraph.csv" AS line FIELDTERMINATOR ',' WITH line WHERE EXISTS(line._id) AND line._labels = ":SudocUnica" CREATE (p:SudocUnica {initId:line._id,ppn:line.ppn,issn:line.issn,titre:line.titre,controle:line.controle,type:line.type,degre:line.degre}) return p

LOAD CSV WITH HEADERS FROM "https://raw.githubusercontent.com/gegedenice/divers-files/master/exportedSudocpsGraph.csv" AS line FIELDTERMINATOR ',' WITH line WHERE EXISTS(line._id) AND line._labels = ":SudocNotUnica" CREATE (p:SudocNotUnica {initId:line._id,ppn:line.ppn,issn:line.issn,titre:line.titre,controle:line.controle,type:line.type,degre:line.degre}) return p

LOAD CSV WITH HEADERS FROM "https://raw.githubusercontent.com/gegedenice/divers-files/master/exportedSudocpsGraph.csv" AS line FIELDTERMINATOR ',' WITH line WHERE EXISTS(line._id) AND line._labels = ":BnfPresselocale" CREATE (p:BnfPresselocale {initId:line._id,ark:line.ark,issn:line.issn,titre:line.titre,edition:line.edition,type:line.type,degre:line.degre}) return p

LOAD CSV WITH HEADERS FROM "https://raw.githubusercontent.com/gegedenice/divers-files/master/exportedSudocpsGraph.csv" AS line FIELDTERMINATOR ',' WITH line WHERE EXISTS(line._id) AND line._labels = ":Numerisation" CREATE (p:Numerisation {initId:line._id,url:line.url,etab:line.etab,type:line.type,degre:line.degre}) return p
  • Relations

LOAD CSV WITH HEADERS FROM "https://raw.githubusercontent.com/gegedenice/divers-files/master/exportedSudocpsGraph.csv" AS line FIELDTERMINATOR ',' WITH line WHERE line._type = "LOCATED" MATCH (b:Bib),(d:Dpt)  WHERE b.initId=line._start AND d.initId=line._end CREATE (b)-[:LOCATED]->(d) return *

LOAD CSV WITH HEADERS FROM "https://raw.githubusercontent.com/gegedenice/divers-files/master/exportedSudocpsGraph.csv" AS line FIELDTERMINATOR ',' WITH line WHERE line._type = "OWNED_BY" MATCH (s),(b:Bib)  WHERE s.initId=line._start AND b.initId=line._end CREATE (s)-[:OWNED_BY {etat_de_collection:line.etat_de_collection}]->(b) return *

LOAD CSV WITH HEADERS FROM "https://raw.githubusercontent.com/gegedenice/divers-files/master/exportedSudocpsGraph.csv" AS line FIELDTERMINATOR ',' WITH line WHERE line._type = "IS_ABOUT" MATCH (b:BnfPresselocale),(d:Dpt)  WHERE b.initId=line._start AND d.initId=line._end CREATE (b)-[:IS_ABOUT]->(d) return *

LOAD CSV WITH HEADERS FROM "https://raw.githubusercontent.com/gegedenice/divers-files/master/exportedSudocpsGraph.csv" AS line FIELDTERMINATOR ',' WITH line WHERE line._type = "SAME_AS" MATCH (b:BnfPresselocale),(s)  WHERE s.initId=line._start AND b.initId=line._end CREATE (s)-[:SAME_AS]->(b) return *

LOAD CSV WITH HEADERS FROM "https://raw.githubusercontent.com/gegedenice/divers-files/master/exportedSudocpsGraph.csv" AS line FIELDTERMINATOR ',' WITH line WHERE line._type = "HAS_VERSION" MATCH (b:BnfPresselocale),(n:Numerisation)  WHERE b.initId=line._start AND n.initId=line._end CREATE (b)-[:HAS_VERSION]->(n) return *
  • IMPORTANT

Lors de l’import, des attributs vides sont créés pour chaque valeur manquante dans le fichier, il faut les supprimer ensuite du graphe car cela peut fausser le résultat des requêtes depuis l’application (notamment celles sur l’ISSN)

match (s:SudocUnica) where s.issn = "" REMOVE s.issn return *
match (s:BnfPresselocale) where s.issn = "" REMOVE s.issn return *
match (s:SudocUnica) where s.controle = "" REMOVE s.controle return *
match (s:SudocNotUnica) where s.controle = "" REMOVE s.controle return *
We can make this file beautiful and searchable if this error is corrected: No commas found in this CSV file in line 0.
ppn
03794651X
040130770
040132064
037127675
037950479
040133613
040175375
038989239
040130754
037127772
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment