Source code for langchain_community.graph_vectorstores.networkx
"""Utilities for using Graph Vector Stores with networkx."""importtypingfromlangchain_core.documentsimportDocumentfromlangchain_community.graph_vectorstores.linksimportget_linksiftyping.TYPE_CHECKING:importnetworkxasnx
[docs]defdocuments_to_networkx(documents:typing.Iterable[Document],*,tag_nodes:bool=True,)->"nx.DiGraph":"""Return the networkx directed graph corresponding to the documents. Args: documents: The documents to convenrt to networkx. tag_nodes: If `True`, each tag will be rendered as a node, with edges to/from the corresponding documents. If `False`, edges will be between documents, with a label corresponding to the tag(s) connecting them. """importnetworkxasnxgraph=nx.DiGraph()tag_ids:typing.Dict[typing.Tuple[str,str],str]={}tag_labels:typing.Dict[str,str]={}documents_by_incoming:typing.Dict[str,typing.Set[str]]={}# First pass:# - Register tag IDs for each unique (kind, tag).# - If rendering tag nodes, add them to the graph.# - If not rendering tag nodes, create a dictionary of documents by incoming tags.fordocumentindocuments:ifdocument.idisNone:raiseValueError(f"Illegal graph document without ID: {document}")forlinkinget_links(document):tag_key=(link.kind,link.tag)tag_id=tag_ids.get(tag_key)iftag_idisNone:tag_id=f"tag_{len(tag_ids)}"tag_ids[tag_key]=tag_idiftag_nodes:graph.add_node(tag_id,label=f"{link.kind}:{link.tag}")ifnottag_nodesand(link.direction=="in"orlink.direction=="bidir"):tag_labels[tag_id]=f"{link.kind}:{link.tag}"documents_by_incoming.setdefault(tag_id,set()).add(document.id)# Second pass:# - Render document nodes# - If rendering tag nodes, render edges to/from documents and tag nodes.# - If not rendering tag nodes, render edges to/from documents based on tags.fordocumentindocuments:graph.add_node(document.id,text=document.page_content)targets:typing.Dict[str,typing.List[str]]={}forlinkinget_links(document):tag_id=tag_ids[(link.kind,link.tag)]iftag_nodes:iflink.direction=="in"orlink.direction=="bidir":graph.add_edge(tag_id,document.id)iflink.direction=="out"orlink.direction=="bidir":graph.add_edge(document.id,tag_id)else:iflink.direction=="out"orlink.direction=="bidir":label=tag_labels[tag_id]fortargetindocuments_by_incoming[tag_id]:iftarget!=document.id:targets.setdefault(target,[]).append(label)# Avoid a multigraph by collecting the list of labels for each edge.ifnottag_nodes:fortarget,labelsintargets.items():graph.add_edge(document.id,target,label=str(labels))returngraph