<jupyter_start><jupyter_text>NeomodelNeomodel est un OGM (Object graph Mapping) python.La documentation est très bien faite https://neomodel.readthedocs.io  Configuration d'accès<jupyter_code>from neomodel import (config, db, StructuredNode, StructuredRel, StringProperty, IntegerProperty,
    UniqueIdProperty, RelationshipTo, RelationshipFrom)

config.DATABASE_URL = 'bolt://neo4j:neo4j@localhost:7687'
config.AUTO_INSTALL_LABELS = True

db.set_connection(config.DATABASE_URL)<jupyter_output><empty_output><jupyter_text>*Nettoyage de la base*<jupyter_code>db.cypher_query('MATCH (n) DETACH DELETE n')<jupyter_output><empty_output><jupyter_text>Définition du domaine<jupyter_code># Modèle de relation    
class WorkIn(StructuredRel):
    function = StringProperty()


# Class personne
class Person(StructuredNode):
    # properties
    name = StringProperty(unique_index=True, required=True)
    age = IntegerProperty()

    # relation simple
    service = RelationshipTo('Service', 'MEMBER_OF')
    
    # relation simple avec modèle
    projects = RelationshipTo('Project', 'WORK_IN', model=WorkIn)
    
    
class Service(StructuredNode):
    name = StringProperty(unique_index=True, required=True)
    members = RelationshipFrom('Person','MEMBER_OF')

    
class Project(StructuredNode):
    name = StringProperty(unique_index=True, required=True)
    workers = RelationshipFrom('Person','WORK_IN',model=WorkIn)<jupyter_output><empty_output><jupyter_text>Installation des labels et des indexes<jupyter_code>from neomodel import install_labels
install_labels(Person)
install_labels(Project)
install_labels(Service)
roxanne = Person(name='Roxanne')
roxanne.save()<jupyter_output><empty_output><jupyter_text>Modification<jupyter_code>roxanne.age = 32
roxanne.save()<jupyter_output><empty_output><jupyter_text>Détection de doublon<jupyter_code>try:
    altRoxanne = Person(name='Roxanne')
    altRoxanne.save()
except Exception as e:
    print(e, type(e))<jupyter_output><empty_output><jupyter_text>Détection d'invalidité<jupyter_code>roxanne.age = 'FOO'
try:
    roxanne.save()
except Exception as e:
    print(e, type(e))<jupyter_output><empty_output><jupyter_text>Suppression<jupyter_code>roxanne.delete()<jupyter_output><empty_output><jupyter_text>Import de lab2000<jupyter_code>import json 
with open('data/lab2000.json','r') as f:
    lab = json.load(f)<jupyter_output><empty_output><jupyter_text>Import des projets<jupyter_code>for project in lab['projects']:
    print(Project.get_or_create({'name': project}))<jupyter_output><empty_output><jupyter_text>Import des services<jupyter_code>for service in lab['services']:
    print(Service.get_or_create({'name': service}))<jupyter_output><empty_output><jupyter_text>Création des relations<jupyter_code>for person in lab['persons']:
    
    servNode = Service.nodes.get(name=person['service'])

    persNode = Person.get_or_create({'name': person['name']})[0]
    persNode.service.connect(servNode)
    
    for project in person['projects']:
        projNode = Project.nodes.get(name=project['name'])
        persNode.projects.connect(projNode, {'function':project['function']})
     
    persNode.save()<jupyter_output><empty_output><jupyter_text>Détection de violation sur les relations<jupyter_code>sophie = Person.nodes.get(name='<NAME>')
print(sophie.service.get())

#----Error ----
try:
    sophie.service.connect(Person(name='Foo'))
except ValueError as ve:
    assert str(ve) == 'Expected node of class Service'<jupyter_output><empty_output><jupyter_text>Requêtes Cypher<jupyter_code># Class personne
class Person(StructuredNode):
    # properties
    name = StringProperty(unique_index=True, required=True)
    age = IntegerProperty()

    # relation simple
    service = RelationshipTo('Service', 'MEMBER_OF')
    
    # relation simple avec modèle
    projects = RelationshipTo('Project', 'WORK_IN', model=WorkIn)
    
    
    def find_service_members_in_project(self):
        '''
        Finds same service member workin in the same projects.
        
        Returns
        -------
        List
            List of Person 
        '''
        results, columns = self.cypher(
            "MATCH (a)-[:MEMBER_OF]->(s:Service) \
            WHERE id(a)={self} \
            MATCH (a)-[:WORK_IN]->(p:Project)<-[:WORK_IN]-(b:Person)-[:MEMBER_OF]->(s) \
            WHERE id(a) <> id(b) \
            RETURN b")
        return [self.inflate(row[0]) for row in results]
tracey = Person.nodes.get(name='<NAME>')
print(tracey.service.get())

members = tracey.find_service_members_in_project()

print(members)

for m in members:
    print(m.service.get())<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12669391266939126, 'fraction_numerical': 0.003871800387180039, 'mean_word_length': 5.142668428005284, 'pattern_counts': {'":': 0, '<': 61, '<?xml version=': 0, '>': 63, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '14', 'dir': 'jupyter-structured-clean-dedup', 'id': '207413', 'license': 'Apache-2.0', 'n_tokens_mistral': 1604, 'n_tokens_neox': 1552, 'n_words': 257, 'path': 'notebooks/neomodel.ipynb', 'repo_name': 'reseau-loops/cafe181204_neo4j', 'size': '4665'}