Construindo uma base de conhecimento e gráficos de visualização para RAG com MongoDB
Prasad Pillalamarri, Shounak Acharya12 min read • Published Sep 02, 2024 • Updated Sep 02, 2024
Avalie esse Tutorial
Várias soluções fornecem dados ricos para melhorar o desempenho dos sistemas RAG. Cada uma dessas alternativas oferece pontos fortes diferentes, e a escolha depende dos requisitos específicos do sistema RAG, como o tipo de dados que estão sendo usados, a complexidade das queries e a qualidade desejada do texto gerado. Na prática, a combinação de vários desses métodos geralmente produz os melhores resultados, aproveitando suas respectivas vantagens para aprimorar os processos de recuperação e geração.
O MongoDB fornece suporte para implementar pesquisa vetorial para recuperação rápida, pré-filtros, pesquisa híbrida e bases de conhecimento. Todas as opções acima podem ser implementadas imediatamente. Neste artigo, Shouldy e eu gostaria de destacar como o MongoDB — e, mais importante, o document model baseado em JSON — pode ser facilmente usado para construir uma base de conhecimento e armazenar as relações entre entidades e nós em uma arquitetura RAG . Também o estenderemos ainda mais e usaremos o documento JSON como base para construir gráficos de rede hierárquicos ou visualizações baseadas no MongoDB Charts.
Os bancos de dados de documentos armazenam e indexam documentos, permitindo a recuperação rápida com base em queries complexas. Eles são adequados para armazenar grandes coleções de documentos de texto, páginas da web ou artigos. O recuperador pode consultar esses bancos de dados para buscar documentos relevantes com base em palavras-chave ou similaridade semântica, que o gerador usa para produzir um texto coerente.
É útil filtrar os dados para restringir o escopo da pesquisa semântica e garantir que nem todos os vetores sejam considerados para comparação. A opção de filtro $vectorSearch corresponde apenas a BSON valores booleanos, de data, de , ObjectId destring de caracteres e numéricos .
A combinação da pesquisa de texto completo com incorporações vetoriais integra vários métodos de recuperação para aproveitar seus pontos fortes. Por exemplo, a reclassificação baseada em incorporação é usada para recuperação baseada em palavras-chave e, em seguida, uma pesquisa de texto completo é executada. O sistema híbrido primeiro refina a seleção com técnicas semânticas avançadas e, em seguida, restringe os candidatos usando a pesquisa de texto completo antes de passá-lo ao gerador.
Grandes repositórios de informações estruturadas são extraídos de várias fontes. Elas geralmente incluem uma ampla gama de entidades e relacionamentos. O recuperador pode consultar essas bases de conhecimento para buscar fatores e relacionamentos relevantes, aprimorando o contexto e os detalhes do texto gerado.
O MongoDB Charts é uma ferramenta de visualização de dados projetada especificamente para o MongoDB Atlas, oferecendo uma maneira rápida, intuitiva e robusta de visualizar seus dados. Ele oferece suporte a uma ampla variedade de casos de uso, esteja você trabalhando com um cluster dedicado e uma instância sem servidor, aproveitando o Atlas Data Federation para revelar insights valiosos a partir de dados combinados do Atlas e S3 ou visualizando dados arquivados no Online Archive.
Neste artigo, criaremos um gráfico de dependência nas entidades a partir de um números de texto livre usando a classe LLGraphTransformer em LangChain e OpenAI como LLM. Passaremos um texto sobre a história da linguagem de programação Python e solicitaremos que retorne as entidades e seus relacionamentos, conforme mostrado no trecho de código abaixo.
1 llm = ChatOpenAI(temperature=0, model_name="gpt-4-turbo",api_key="YOUR-OPENAI-KEY") 2 3 llm_transformer = LLMGraphTransformer(llm=llm) 4 text = """ 5 Python was invented in the late 1980s by Guido van Rossum at Centrum Wiskunde & Informatica in the Netherlands as a successor to the ABC 6 programming language, which was inspired by SETL capable of exception handling and interfacing with the Amoeba operating system. 7 Its implementation began in December 1989. Python 2.0 was released on 16 October 2000, with many major new features such as list comprehensions, 8 cycle-detecting garbage collection, reference counting, and Unicode support. Python 3.0, released on 3 December 2008, 9 with many of its major features backported to Python 2.6.x and 2.7.x. Releases of Python 3 include the 2to3 utility, 10 which automates the translation of Python 2 code to Python 3. 11 """ 12 documents = [Document(page_content=text)] 13 graph_documents = llm_transformer.convert_to_graph_documents(documents) 14 print(f"Nodes:{graph_documents[0].nodes}") 15 print(f"Relationships:{graph_documents[0].relationships}")
Isso gera uma saída como abaixo, capturando vários nós e seus relacionamentos:
1 Nodes:[Node(id='Python', type='Programming_language'), Node(id='Guido Van Rossum', type='Person'), Node(id='Centrum Wiskunde & Informatica', type='Organization'), Node(id='Netherlands', type='Country'), Node(id='Abc Programming Language', type='Programming_language'), Node(id='Setl', type='Programming_language'), Node(id='Amoeba Operating System', type='Operating_system'), Node(id='Python 2.0', type='Software_version'), Node(id='Python 3.0', type='Software_version'), Node(id='2To3 Utility', type='Software_tool')] 2 Relationships:[Relationship(source=Node(id='Python', type='Programming_language'), target=Node(id='Guido Van Rossum', type='Person'), type='CREATED_BY'), Relationship(source=Node(id='Python', type='Programming_language'), target=Node(id='Centrum Wiskunde & Informatica', type='Organization'), type='DEVELOPED_AT'), Relationship(source=Node(id='Python', type='Programming_language'), target=Node(id='Netherlands', type='Country'), type='DEVELOPED_IN'), Relationship(source=Node(id='Python', type='Programming_language'), target=Node(id='Abc Programming Language', type='Programming_language'), type='SUCCESSOR_OF'), Relationship(source=Node(id='Abc Programming Language', type='Programming_language'), target=Node(id='Setl', type='Programming_language'), type='INSPIRED_BY'), Relationship(source=Node(id='Python', type='Programming_language'), target=Node(id='Amoeba Operating System', type='Operating_system'), type='INTERFACE_WITH'), Relationship(source=Node(id='Python 3.0', type='Software_version'), target=Node(id='Python 2.0', type='Software_version'), type='BACKPORTED_TO'), Relationship(source=Node(id='Python 3.0', type='Software_version'), target=Node(id='2To3 Utility', type='Software_tool'), type='INCLUDES')]
Como pode ser visto na saída acima, o LLMGraphTransformer capturou várias entidades como Python, Guiado vao rossum, Netherlands, etc. e também atribuiu um tipo. Por exemplo, Python é uma linguagem de programação, Guiado vassum é uma pessoa e Netherlands é um país.
O LLMGraphTransformer não apenas identifica nós, mas também gera relacionamentos entre eles. Por exemplo, o resultado acima estabelece que Guiado vai buscar um criador para o Python, uma linguagem de programação. Essa conexão é representada por um objeto de relacionamento , que consiste em uma origem (Python), um destino (Guido vão rossum) e um tipo de relacionamento (CREATED_BY). O resultado demonstra vários desses relacionamentos sendo capturados entre as entidades de nó identificadas.
Agora, usando essas estruturas de dados de nó e relacionamento , podemos criar coleções MongoDB para capturar o gráfico de relacionamento dentro do MongoDB. Neste exemplo, criamos uma coleção para cada um dos tipos de nó — por exemplo, encryption_language, País, Operator_system etc., conforme mostrado abaixo no trecho de código:
1 nodes = graph_documents[0].nodes 2 relationships = graph_documents[0].relationships 3 collections = set() 4 for node in nodes: 5 collections.add(node.type) 6 print(collections) 7 try: 8 uri = "MONGO-DB-URL" 9 client = MongoClient(uri) 10 database = client["generic_graph"] 11 for collection in collections: 12 database.create_collection(collection) 13 except Exception as e: 14 print(e) 15 finally: 16 client.close()
Isso cria uma coleção com base nos tipos de nó, conforme mostrado na saída abaixo:
1 {'Programming_language', 'Software_tool', 'Person', 'Software_version', 'Organization', 'Country', 'Operating_system'}
Podemos aplicar outros padrões de design, como padrões de design polimórficos, para criar uma única coleção com vários tipos de objeto . No entanto, nesses casos, o código precisa ser modificado com base no conhecimento do domínio no grafo. Em nosso exemplo, mantivemos o padrão mais genérico para que o mesmo padrão possa ser utilizado para gerar collections e relacionamentos correspondentes sem muita modificação de código para qualquer base de conhecimento.
Agora, para capturar relacionamentos entre os documentos nas collections, usaremos vinculação. Em nosso caso, iteramos pelas listas de relacionamento e façamos o seguinte:
- Para a origem do relacionamento, criamos um atributo de array no documento.
- O valor do atributo array é o destino do tipo de relacionamento .
- Criamos esses atributos de array na origem para cada um dos relacionamentos em que o objeto atual é a origem.
Por exemplo, na coleção Linguagem de programação, teremos Python como um dos documentos. Agora, no documento do Python, teremos atributos de array para DEVELOPED_IN, CREATED_BY, DEVELOPED_AT,SUCCESSOR_OF eInterFACE_WITH, conforme mostrado na captura de tela abaixo:
Da mesma forma, por exemplo, a linguagem de programação Amazon, que é uma antecessora do Python, foi inspirada em Setl, como mostrado na captura de tela a seguir. Observe que ambos são da mesma coleção chamada Programing_language:
No entanto, se observarmos corretamente, Setl não tem nenhum vínculo, pois não havia relacionamentos definidos na saída do LLMGraphTransformer.
Os seguintes trechos de código mostram como chegar às coleções acima.
1 #Figuring out all relationship types per node types 2 node_relationship_types = {} 3 for node in nodes: 4 #print(f'On Node {node.id}') 5 node_relationship_types[node.id] = set() 6 for rel in relationships: 7 #print(f'Looking at Relationship for {rel.source.id}') 8 if rel.source.id == node.id: 9 node_relationship_types[node.id].add(rel.type) 10 print(node_relationship_types)
O código acima cria um dicionário de todos os tipos de relacionamento exclusivos por fonte a partir da lista de relacionamento LLMGraphTransformer e fornece a saída conforme abaixo:
1 {'Python': {'DEVELOPED_IN', 'CREATED_BY', 'DEVELOPED_AT', 'SUCCESSOR_OF', 'INTERFACE_WITH'}, 'Guido Van Rossum': set(), 'Centrum Wiskunde & Informatica': set(), 'Netherlands': set(), 'Abc Programming Language': {'INSPIRED_BY'}, 'Setl': set(), 'Amoeba Operating System': set(), 'Python 2.0': set(), 'Python 3.0': {'BACKPORTED_TO'}, '2To3 Utility': {'TRANSLATES_TO'}}
Quando soubermos de todos os relacionamentos, criaremos os documentos para cada tipo de coleção, vinculando outras coleções no caminho e inserindo no MongoDB como mostrado no trecho a seguir:
1 mongo_documents = [] 2 for node in nodes: 3 document_dict = {} 4 document_dict['id'] = node.id 5 document_dict['type'] = node.type 6 document_relations = node_relationship_types[node.id] 7 for document_relation in document_relations: 8 document_dict[document_relation] = [] 9 for rel in relationships: 10 if rel.source.id == node.id: 11 document_dict[rel.type].append(rel.target.id) 12 mongo_documents.append(document_dict) 13 print(mongo_documents)
O trecho acima gera primeiro documentos a serem inseridos nas coleções correspondentes com todos os detalhes de vinculação a outros documentos, conforme mostrado na saída abaixo:
1 [{'id': 'Python', 'type': 'Programming_language', 'DEVELOPED_IN': ['Netherlands'], 'CREATED_BY': ['Guido Van Rossum'], 'DEVELOPED_AT': ['Centrum Wiskunde & Informatica'], 'SUCCESSOR_OF': ['Abc Programming Language'], 'INTERFACE_WITH': ['Amoeba Operating System']}, {'id': 'Guido Van Rossum', 'type': 'Person'}, {'id': 'Centrum Wiskunde & Informatica', 'type': 'Organization'}, {'id': 'Netherlands', 'type': 'Country'}, {'id': 'Abc Programming Language', 'type': 'Programming_language', 'INSPIRED_BY': ['Setl']}, {'id': 'Setl', 'type': 'Programming_language'}, {'id': 'Amoeba Operating System', 'type': 'Operating_system'}, {'id': 'Python 2.0', 'type': 'Software_version'}, {'id': 'Python 3.0', 'type': 'Software_version', 'BACKPORTED_TO': ['Python 2.0']}, {'id': '2To3 Utility', 'type': 'Software_tool', 'TRANSLATES_TO': ['Python 3.0']}]
Por fim, adicionamos esses documentos ao MongoDB. Calculamos a coleção a ser inserida observando o campo "type " que inserimos nos documentos na etapa acima:
1 try: 2 uri = "YOUR-MONGO-URL" 3 client = MongoClient(uri) 4 database = client["generic_graph"] 5 for mongo_document in mongo_documents: 6 collection = database[mongo_document['type']] 7 collection.insert_one(mongo_document) 8 except Exception as e: 9 print(e) 10 finally: 11 client.close()
Quando você escrever uma vez e ler muitos casos de uso (1+W/99R) ou escrever várias vezes e ler com frequência (20W/80R), é recomendável pré-calcular o esquema de renderização esperado pelo seu mecanismo de renderização — no nosso caso, d3.js — e salve-o junto com seus documentos do MongoDB . A saída a seguir mostra o esquema do documento Python na coleção Programing_language que mostramos na última seção, que agora armazena todos os nós de destino e bordas para os nós, que começam a partir desse nó:
1 [{'CREATED_BY': ['Guido Van Rossum'], 2 'DEVELOPED_AT': ['Centrum Wiskunde & Informatica'], 3 'DEVELOPED_IN': ['Netherlands'], 4 'INTERFACE_WITH': ['Amoeba Operating System'], 5 'SUCCESSOR_OF': ['Abc Programming Language'], 6 'd3_edges': [{'linkName': 'CREATED_BY', 7 'source': 'Python', 8 'strength': 0.7, 9 'target': 'Guido Van Rossum'}, 10 {'linkName': 'DEVELOPED_AT', 11 'source': 'Python', 12 'strength': 0.7, 13 'target': 'Centrum Wiskunde & Informatica'}, 14 {'linkName': 'DEVELOPED_IN', 15 'source': 'Python', 16 'strength': 0.7, 17 'target': 'Netherlands'}, 18 {'linkName': 'SUCCESSOR_OF', 19 'source': 'Python', 20 'strength': 0.7, 21 'target': 'Abc Programming Language'}, 22 {'linkName': 'INTERFACE_WITH', 23 'source': 'Python', 24 'strength': 0.7, 25 'target': 'Amoeba Operating System'}], 26 'd3_source_node': {'group': 0, 'id': 'Python', 'label': 'Python', 'level': 1}, 27 'd3_target_nodes': [{'group': 1, 28 'id': 'Guido Van Rossum', 29 'label': 'Guido Van Rossum', 30 'level': 2}, 31 {'group': 1, 32 'id': 'Centrum Wiskunde & Informatica', 33 'label': 'Centrum Wiskunde & Informatica', 34 'level': 2}, 35 {'group': 1, 36 'id': 'Netherlands', 37 'label': 'Netherlands', 38 'level': 2}, 39 {'group': 1, 40 'id': 'Abc Programming Language', 41 'label': 'Abc Programming Language', 42 'level': 2}, 43 {'group': 1, 44 'id': 'Amoeba Operating System', 45 'label': 'Amoeba Operating System', 46 'level': 2}], 47 'id': 'Python', 48 'type': 'Programming_language'}]
Isso pode ser feito durante a criação dos documentos mongo a partir do gráfico, conforme mostrado no trecho a seguir. Observe que o código para criar coleções ainda seria o mesmo mencionado na seção anterior.
1 mongo_documents = [] 2 for node in nodes: 3 document_dict = {} 4 document_dict['id'] = node.id 5 document_dict['type'] = node.type 6 document_dict['d3_edges'] = [] 7 document_dict['d3_target_nodes'] = [] 8 document_dict['d3_source_node'] = {'id':node.id,'group':0,'level':1,'label':node.id} 9 document_relations = node_relationship_types[node.id] 10 for document_relation in document_relations: 11 document_dict[document_relation] = [] 12 for rel in relationships: 13 if rel.source.id == node.id: 14 document_dict[rel.type].append(rel.target.id) 15 document_dict['d3_target_nodes'].append({'id':rel.target.id,'group':1,'level':2,'label':rel.target.id}) 16 document_dict['d3_edges'].append({'source':node.id,'target':rel.target.id,'strength':0.7,'linkName':rel.type}) 17 mongo_documents.append(document_dict) 18 pprint(mongo_documents)
O código acima mostra a captura e o armazenamento de relações de um nível. Os mesmos conceitos podem ser utilizados para armazenar relações de nível N por documento com base em seu caso de uso, que segue o padrão desubconjunto ao projetar dados MongoDB .
Você pode aproveitar todos os tipos de gráficos. Os grafos hierárquicos podem estar em uma estrutura de árvore, grafos direcionados por força disjuntos ou arcos hierárquicos. Abaixo, os documentos JSON podem alimentar os conjuntos de dados para exibir esses gráficos.
Tipo de gráfico 1:
1 Object {source: "X1", target: "X2", type: "suit"} 2 Object {source: "X2", target: "X3", type: "resolved"} 3 Object {source: "X3", target: "X4", type: "suit"} 4 Object {source: "X4", target: "X1", type: "suit"} 5 columns: Array(3) [ 6 0: "source" 7 1: "target" 8 2: "type" 9 ]
Tipo de gráfico 2:
1 Object {source: "Napoleon", target: "Myriel", value: 1} 2 Object {source: "Mlle.Baptistine", target: "Myriel", value: 8} 3 Object {source: "Mme.Magloire", target: "Myriel", value: 10} 4 Object {source: "Mme.Magloire", target: "Mlle.Baptistine", value: 6} 5 Object {source: "Cravatte", target: "Myriel", value: 1} 6 Object {source: "Count", target: "Myriel", value: 2} 7 Object {source: "OldMan", target: "Myriel", value: 1}
Tipo de gráfico 3:
1 data = Object { 2 name: "flare" 3 children: Array(10) [ 4 0: Object { 5 name: "analytics" 6 children: Array(3) [ 7 0: Object {name: "cluster", children: Array(4)} 8 1: Object {name: "graph", children: Array(5)} 9 2: Object {name: "optimization", children: Array(1)} 10 ] 11 } 12 1: Object {name: "animate", children: Array(12)} 13 2: Object {name: "data", children: Array(7)} 14 3: Object {name: "display", children: Array(4)} 15 4: Object { 16 name: "flex" 17 children: Array(1) [ 18 0: Object { 19 } 20 ] 21 }
Em nosso caso de uso, usamos o d3.js grafo direcionado à força para criar um exemplo de visualização para a coleção de programação de linguagens. Agora, d3.js espera duas arrays, ou seja, nós e links, em um objeto JSON, onde cada array é um JSON capturando as propriedades de nós e relacionamentos, respectivamente. A estrutura se parece com algo abaixo:
1 {nodes = [{'id': 'Python', 'group': 0, 'level': 1, 'label': 'Python'}, {'id': 'Netherlands', 'group': 1, 'level': 2, 'label': 'Netherlands'}], 2 links = [{'source': 'Python', 'target': 'Netherlands', 'strength': 0.7}, {'source': 'Python', 'target': 'Guido Van Rossum', 'strength': 0.7}]}
Cada um dos objetos JSON dentro das arrays tem alguns campos obrigatórios e alguns campos opcionais. Por exemplo, os nós devem ter "id " como um campo obrigatório . Da mesma forma, objetos de relacionamento devem ter "source " e "target " como campos obrigatórios.
Para criar essa estrutura a partir da nossa coleção Linguagem de programação, usamos uma pesquisa de grafos que cria recursivamente o relacionamento entre o Python e sua antecessora, a linguagem de programação Apache. Finalmente, isso vai para Setl, a linguagem da qual oABC foi inspirada.
O graphlookup do MongoDB executa uma pesquisa recursiva em uma coleção, com opções para restringir a pesquisa por profundidade de recursão e filtro de consulta.
O processo $graphLookup funciona da seguinte forma:
- Documentos de entrada são processados no estágio $graphLookup de um pipeline de agregação .
- A pesquisa é direcionada para a coleção especificada pelo parâmetro "from ".
- Para cada documento de entrada, a pesquisa começa com o valor especificado por startWith.
- $graphLookup compara este valor startWith com o campo indicado por connectToField em outros documentos dentro da collection "from ".
- Quando uma correspondência é encontrada, $graphLookup recupera o valor de connectFromField e verifica outros documentos na coleção "from " para valores de connectToField correspondentes. Em seguida, os documentos correspondentes são adicionados a uma array especificada pelo parâmetro as.
- Esse processo recursivo continua até que não haja mais correspondências encontradas ou que a profundidade máxima da recursão, definida por maxDepth, seja atingida.
- Finalmente, $graphLookup acrescenta a array ao documento de entrada original e conclui sua pesquisa em todos os documentos de entrada.
Finalmente, criamos os nós e arrays de relacionamento e os salvamos em um arquivo JSON. Observe que também adicionamos Etiquetas de Link, que mostram os tipos de relacionamento entre os nós:
1 try: 2 uri = "YOUR-MONGO-URL" 3 client = MongoClient(uri) 4 database = client["generic_graph"] 5 language_collection = database["Programming_language"] 6 language_pipeline = [ 7 { 8 '$graphLookup': { 9 'from': 'Programming_language', 10 'startWith': '$SUCCESSOR_OF', 11 'connectFromField': 'id', 12 'connectToField': 'id', 13 'as': 'relations', 14 'maxDepth': 2 15 } 16 }, { 17 '$unwind': { 18 'path': '$relations', 19 'preserveNullAndEmptyArrays': False 20 } 21 } 22 ] 23 lang_aggCursor = language_collection.aggregate(language_pipeline) 24 nodes=[] 25 links=[] 26 for document in lang_aggCursor: 27 print(document) 28 source_node_dict = {} 29 source_node_dict['id'] = document.get('id') 30 source_node_dict['group'] = 0 31 source_node_dict['level'] = 1 32 source_node_dict['label'] = document.get('id') 33 nodes.append(source_node_dict) 34 for key in document.keys(): 35 print(key) 36 target_node_dict = {} 37 link_dict = {} 38 if key=='_id' or key=='id' or key=='type' or key=='SUCCESSOR_OF': 39 continue 40 elif key=='relations': 41 target_node_dict['id']=document[key]['id'] 42 target_node_dict['group']=1 43 target_node_dict['level']=2 44 target_node_dict['label'] = document[key]['id'] 45 inspired_node_dict = {} 46 inspired_node_dict['id'] = document[key]['INSPIRED_BY'][0] 47 inspired_node_dict['group'] = 1 48 inspired_node_dict['level'] = 2 49 inspired_node_dict['label'] = document[key]['INSPIRED_BY'][0] 50 link_dict['source'] = target_node_dict.get('id') 51 link_dict['target'] = inspired_node_dict.get('id') 52 link_dict['strength'] = 0.7 53 link_dict['linkName'] = 'INSPIRED_BY' 54 link_dict_2 = {} 55 link_dict_2['source'] = source_node_dict.get('id') 56 link_dict_2['target'] = target_node_dict.get('id') 57 link_dict_2['strength'] = 0.7 58 link_dict_2['linkName'] = 'SUCCESSOR_OF' 59 nodes.append(target_node_dict) 60 nodes.append(inspired_node_dict) 61 links.append(link_dict) 62 links.append(link_dict_2) 63 continue 64 else: 65 target_node_dict['id'] = document[key][0] 66 target_node_dict['group']=1 67 target_node_dict['level']=2 68 target_node_dict['label'] = document[key][0] 69 link_dict['source'] = source_node_dict.get('id') 70 link_dict['target'] = target_node_dict.get('id') 71 link_dict['strength'] = 0.7 72 link_dict['linkName'] = key 73 nodes.append(target_node_dict) 74 links.append(link_dict) 75 print(nodes) 76 print(links) 77 except Exception as e: 78 print(e) 79 finally: 80 client.close() 81 nodes_links = {"nodes": nodes,"links":links } 82 import json 83 with open("python-dependencies.json",'w') as f: 84 json.dump(nodes_links,f,indent=1)
Isso cria o arquivo python-dependecies.json cujo conteúdo é mostrado abaixo com rótulos de nós, bem como links:
1 {nodes=[{'id': 'Python', 'group': 0, 'level': 1, 'label': 'Python'}, {'id': 'Netherlands', 'group': 1, 'level': 2, 'label': 'Netherlands'}, {'id': 'Guido Van Rossum', 'group': 1, 'level': 2, 'label': 'Guido Van Rossum'}, {'id': 'Centrum Wiskunde & Informatica', 'group': 1, 'level': 2, 'label': 'Centrum Wiskunde & Informatica'}, {'id': 'Amoeba Operating System', 'group': 1, 'level': 2, 'label': 'Amoeba Operating System'}, {'id': 'Abc Programming Language', 'group': 1, 'level': 2, 'label': 'Abc Programming Language'}, {'id': 'Setl', 'group': 1, 'level': 2, 'label': 'Setl'}], 2 links=[{'source': 'Python', 'target': 'Netherlands', 'strength': 0.7, 'linkName': 'DEVELOPED_IN'}, {'source': 'Python', 'target': 'Guido Van Rossum', 'strength': 0.7, 'linkName': 'CREATED_BY'}, {'source': 'Python', 'target': 'Centrum Wiskunde & Informatica', 'strength': 0.7, 'linkName': 'DEVELOPED_AT'}, {'source': 'Python', 'target': 'Amoeba Operating System', 'strength': 0.7, 'linkName': 'INTERFACE_WITH'}, {'source': 'Abc Programming Language', 'target': 'Setl', 'strength': 0.7, 'linkName': 'INSPIRED_BY'}, {'source': 'Python', 'target': 'Abc Programming Language', 'strength': 0.7, 'linkName': 'SUCCESSOR_OF'}]}
Em seguida, usamos esse JSON arquivo para criar a array de nós e links no3 código d.js. Reutilizamos parte do código da do Github URL e atualizamos as etiquetas de link lá. Finalmente, executamos um servidor de nó HTTP local e renderizamos o HTML. A saída tem a seguinte aparência:
Como podemos ver, podemos exibir o gráfico de relacionamento que foi capturado por nossas coleções do MongoDB usando d3.js.
Se adotarmos a abordagem de relações incorporadas, a renderização se torna ainda mais fácil e genérica. O código a seguir é lido de documentos que têm os nós de destino incorporados e dados de bordas nos próprios documentos. O simples fato de fazer uma busca em todos os documentos de uma collection nos fornece todos os nós e bordas necessários para formar o grafo, conforme mostrado no trecho de código abaixo:
1 master_lookup_set = set() 2 nodes=[] 3 links=[] 4 try: 5 uri = "YOUR-MONGODB-CLUSTER-URL" 6 client = MongoClient(uri) 7 database = client["embedded_graph_2"] 8 collection = database["Programming_language"] 9 cursor = collection.find({},{'_id':0,'id':1,'d3_edges':1,'d3_target_nodes':1,'d3_source_node':1}) 10 for document in cursor: 11 print(document) 12 if document['id'] not in master_lookup_set: 13 master_lookup_set.add(document['id']) 14 nodes.append(document['d3_source_node']) 15 for link in document['d3_edges']: 16 links.append(link) 17 master_lookup_set.add(link['target']) 18 for target_node in document['d3_target_nodes']: 19 nodes.append(target_node) 20 else: 21 for link in document['d3_edges']: 22 links.append(link) 23 except Exception as e: 24 print(e) 25 finally: 26 client.close() 27 28 nodes_links = {"nodes": nodes,"links":links } 29 import json 30 with open("python-dependencies_embedded_2.json",'w') as f: 31 json.dump(nodes_links,f,indent=1)
Isso gera o arquivo "python-dependencies_embedded_2.json ", que, quando inserido no d3.js Código HTML, resulta no seguinte gráfico, que é exatamente como o mostrado acima:
Como você pode ver, este é um código muito mais simples e utilizável, especialmente quando precisamos visualizar nós e relacionamentos.
Este artigo fornece todos os pontos de integração e trechos de código que ajudam os desenvolvedores a aproveitar uma base de conhecimento com o MongoDB para arquiteturas RAG. Isso demonstra que MongoDB JSON o documento do é a base para gerar modelos de gráficos e visualizações com base no MongoDB Atlas Charts. Além disso, observe que a maior parte do código está pronta para uso, com foco na principal proposição de valor do MongoDB em torno da produtividade do programador.
Interessado em um papel na equipe de pré-vendas de parceiros da MongoDB? Nós temos várias funções abertas **em nossas equipes em todo o mundo e gostaria que você transformasse sua carreia conosco!
Principais comentários nos fóruns
Ainda não há comentários sobre este artigo.