Source code for langchain_community.graphs.falkordb_graph
importwarningsfromtypingimportAny,Dict,List,Optionalfromlangchain_core._apiimportdeprecatedfromlangchain_community.graphs.graph_documentimportGraphDocumentfromlangchain_community.graphs.graph_storeimportGraphStorenode_properties_query="""MATCH (n)WITH keys(n) as keys, labels(n) AS labelsWITH CASE WHEN keys = [] THEN [NULL] ELSE keys END AS keys, labelsUNWIND labels AS labelUNWIND keys AS keyWITH label, collect(DISTINCT key) AS keysRETURN {label:label, keys:keys} AS output"""rel_properties_query="""MATCH ()-[r]->()WITH keys(r) as keys, type(r) AS typesWITH CASE WHEN keys = [] THEN [NULL] ELSE keys END AS keys, types UNWIND types AS typeUNWIND keys AS key WITH type,collect(DISTINCT key) AS keys RETURN {types:type, keys:keys} AS output"""rel_query="""MATCH (n)-[r]->(m)UNWIND labels(n) as src_labelUNWIND labels(m) as dst_labelUNWIND type(r) as rel_typeRETURN DISTINCT {start: src_label, type: rel_type, end: dst_label} AS output"""
[docs]classFalkorDBGraph(GraphStore):"""FalkorDB wrapper for graph operations. *Security note*: Make sure that the database connection uses credentials that are narrowly-scoped to only include necessary permissions. Failure to do so may result in data corruption or loss, since the calling code may attempt commands that would result in deletion, mutation of data if appropriately prompted or reading sensitive data if such data is present in the database. The best way to guard against such negative outcomes is to (as appropriate) limit the permissions granted to the credentials used with this tool. See https://python.langchain.com/docs/security for more information. """
[docs]def__init__(self,database:str,host:str="localhost",port:int=6379,username:Optional[str]=None,password:Optional[str]=None,ssl:bool=False,)->None:"""Create a new FalkorDB graph wrapper instance."""try:self.__init_falkordb_connection(database,host,port,username,password,ssl)exceptImportError:try:# Falls back to using the redis package just for backwards compatibilityself.__init_redis_connection(database,host,port,username,password,ssl)exceptImportError:raiseImportError("Could not import falkordb python package. ""Please install it with `pip install falkordb`.")self.schema:str=""self.structured_schema:Dict[str,Any]={}try:self.refresh_schema()exceptExceptionase:raiseValueError(f"Could not refresh schema. Error: {e}")
def__init_falkordb_connection(self,database:str,host:str="localhost",port:int=6379,username:Optional[str]=None,password:Optional[str]=None,ssl:bool=False,)->None:fromfalkordbimportFalkorDBtry:self._driver=FalkorDB(host=host,port=port,username=username,password=password,ssl=ssl)exceptExceptionase:raiseConnectionError(f"Failed to connect to FalkorDB: {e}")self._graph=self._driver.select_graph(database)@deprecated("0.0.31",alternative="__init_falkordb_connection")def__init_redis_connection(self,database:str,host:str="localhost",port:int=6379,username:Optional[str]=None,password:Optional[str]=None,ssl:bool=False,)->None:importredisfromredis.commands.graphimportGraph# show deprecation warningwarnings.warn("Using the redis package is deprecated. ""Please use the falkordb package instead, ""install it with `pip install falkordb`.",DeprecationWarning,)self._driver=redis.Redis(host=host,port=port,username=username,password=password,ssl=ssl)self._graph=Graph(self._driver,database)@propertydefget_schema(self)->str:"""Returns the schema of the FalkorDB database"""returnself.schema@propertydefget_structured_schema(self)->Dict[str,Any]:"""Returns the structured schema of the Graph"""returnself.structured_schema
[docs]defrefresh_schema(self)->None:"""Refreshes the schema of the FalkorDB database"""node_properties:List[Any]=self.query(node_properties_query)rel_properties:List[Any]=self.query(rel_properties_query)relationships:List[Any]=self.query(rel_query)self.structured_schema={"node_props":{el[0]["label"]:el[0]["keys"]forelinnode_properties},"rel_props":{el[0]["types"]:el[0]["keys"]forelinrel_properties},"relationships":[el[0]forelinrelationships],}self.schema=(f"Node properties: {node_properties}\n"f"Relationships properties: {rel_properties}\n"f"Relationships: {relationships}\n")
[docs]defquery(self,query:str,params:dict={})->List[Dict[str,Any]]:"""Query FalkorDB database."""try:data=self._graph.query(query,params)returndata.result_setexceptExceptionase:raiseValueError(f"Generated Cypher Statement is not valid\n{e}")
[docs]defadd_graph_documents(self,graph_documents:List[GraphDocument],include_source:bool=False)->None:""" Take GraphDocument as input as uses it to construct a graph. """fordocumentingraph_documents:# Import nodesfornodeindocument.nodes:self.query((f"MERGE (n:{node.type}{{id:'{node.id}'}}) ""SET n += $properties ""RETURN distinct 'done' AS result"),{"properties":node.properties},)# Import relationshipsforrelindocument.relationships:self.query((f"MATCH (a:{rel.source.type}{{id:'{rel.source.id}'}}), "f"(b:{rel.target.type}{{id:'{rel.target.id}'}}) "f"MERGE (a)-[r:{(rel.type.replace(' ','_').upper())}]->(b) ""SET r += $properties ""RETURN distinct 'done' AS result"),{"properties":rel.properties},)