neo4j.jpg
Cover image for joseph_appsmith

Joseph Petty Verified userVerified user

Head of Developer Relations

Appsmith

Self-Hosted Knowledge Graph with Neo4J and Appsmith

Goal

Deploy Appsmith and Neo4j locally with Docker, create a knowledge graph, and display it in Appsmith

Prerequisites

Overview

This tutorial will cover how to build your own knowledge graph running locally with Neo4j and Appsmith in Docker. Once deployed, you can use any of Appsmith's datasources and integrations to automate creating knowledge graphs from any API or database. 

  1. Deploy Neo4j in Docker

    Open Docker Desktop, enter neo4j in the search bar, and click Run on the top result. After a few minutes, you should have Neo4j downloaded and ready to run on port 7474. 

     

    neo4j

     

    Once the download finishes, expand the Optional settings if you want to modify the default ports, or just click Run to use the defaults. 

    Note: Ensure the port values are not blank. Occasionally the defaults get cleared and you have to type in the default port shown in grey on the right. 

     

    run image

    Click the link in the logs, or go to http://localhost:7474/browser/ to begin setting up a new knowledge graph. 

    Enter neo4j for the user name and password, and click connect. You'll be prompted to set a new password on first login. 

     

    After login, click the option to try the new Neo4j browser, or go to http://localhost:7474/browser/preview. You may be asked to login again. This will access the latest version of the database UI. 

    Then enter the following Cypher query and click the ► Run button in the top right. 

    // Create a Customer node
    CREATE (c:Customer {id: 'C123', name: 'John Doe', email: 'johndoe@example.com'})
    
    // Create a Feature node
    CREATE (f:Feature {id: 'F001', name: 'New Dashboard'})
    
    // Create a Video node
    CREATE (v:Video {id: 'V001', url: 'https://example.com/video.mp4'})
    
    // Create a Ticket node and relate it to the Customer and Feature
    CREATE (t:Ticket {id: 'T1001', description: 'Ticket about New Dashboard feature'})
    CREATE (c)-[:CREATED]->(t)
    CREATE (t)-[:CONCERNS]->(f)
    
    // Create relationship between Ticket and Video
    CREATE (t)-[:HAS_VIDEO]->(v)
    
    cypher

    The cypher query defines the new records and their relationships. 

    Cypher Queries

    Cypher is Neo4j’s graph query language, designed to work intuitively with graph structures by using a declarative syntax similar to SQL but optimized for traversing relationships. 

    Cypher allows you to create, read, update, and delete nodes, relationships, and properties in a Neo4j database efficiently. It employs pattern matching using parenthesis to represent nodes (n) and arrows and square brackets for relationships -[r]->.

    Next, click the * button under relationships to view the new graph. 

    knowledge graph

    Congratulations! You just built a knowledge graph! 

    You can write these cypher queries manually based on your data, or use an LLM to parse unstructured data and create cypher queries automatically. 

  2. Deploy Appsmith In Docker

    Next, search appsmith-ee in Docker, and click run on the latest release. 

    Once the download finishes and the container is running, set up a new account by opening localhost in the browser. 

    Note: This is a fresh install of your own Appsmith server, so you have to create a new account even if you already have an appsmith.com account. 

     

    new account

    On the next screen, choose Authenticated API to set up a new secure API Datasource. 

    Configure the datasource as follows:

    Name Neo4j
    URL http://host.docker.internal:7474
    Authorization Type Basic
    User Name neo4j
    Password YOUR_NEW_PASSWORD

    datasource

    Note: When connecting from one Docker container to another, use host.docker.internal instead of local host. 

    Then click SAVE on the datasource, and add a new API. 

    Set up the new API as follows:

    Name GetGraph
    Method POST
    URL /db/neo4j/tx/commit
    Body Type JSON
    Body
    {{
    {
    "statements": [
      {
       "statement": `MATCH (n)-[r]-(m)
    RETURN n, r, type(r) AS relType, m
    `}
    ]
    }
    }}

     

    neo4j query

     

     

    This should return an object with a results array containing rows of nodes and edges, and metadata. Next, we'll display it in a custom widget. 

     

  3. Knowledge Graph Custom Widget

    Now go to the UI tab and drag in a custom widget. Update the Default Model to pass in the data from the GetGraph query by entering:

    {{ 
    
    {
    	data: GetGraph.data.results
    }
    
    }}

     

    Then click Edit Source to open the custom widget editor. 

    Next, paste in the code for each tab (HTML, Style, JS):

    HTML

    <!DOCTYPE html>
    <html>
      <head>
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.20.1/cytoscape.min.css" />
      </head>
      <body>
        <div id="app" style="width: 100%; height: 100vh;"></div>
        <script src="https://unpkg.com/vue@3.0.0/dist/vue.global.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.20.1/cytoscape.min.js"></script>
      </body>
    </html>

    Style

    #app {
      width: 100%;
      height: 100vh;
    }
    
    .network {
      border: 1px solid gray;
      width: 100%;
      height: 100%;
    }

    JavaScript

    const { createApp, ref, onMounted } = Vue;
    
    appsmith.onReady(()=>{
    	
    	const App = {
      setup() {
        const containerRef = ref(null);
    
        const transformData = (rawData) => {
          const elements = [];
          const nodesSet = new Set();
    
          rawData.forEach(({ row, meta }) => {
            const [source, , relType, target] = row;
            const [sourceMeta, , , targetMeta] = meta;
    
            if (!sourceMeta.deleted && !nodesSet.has(sourceMeta.id)) {
              nodesSet.add(sourceMeta.id);
              elements.push({ data: { id: sourceMeta.id, label: source.name || source.description || source.id, type: sourceMeta.type } });
            }
    
            if (!targetMeta.deleted && !nodesSet.has(targetMeta.id)) {
              nodesSet.add(targetMeta.id);
              elements.push({ data: { id: targetMeta.id, label: target.name || target.description || target.id, type: targetMeta.type } });
            }
    
            if (!sourceMeta.deleted && !targetMeta.deleted) {
              elements.push({ data: { source: sourceMeta.id, target: targetMeta.id, label: relType, type: 'edge' } });
            }
          });
    
          return elements;
        };
    
        onMounted(() => {
          const data = appsmith.model.data ? appsmith.model.data[0].data : [];
          const elements = transformData(data);
    
          cytoscape({
            container: containerRef.value,
            elements,
            style: [
              {
                selector: 'node[type="node"]',
                style: {
                  'label': 'data(label)',
                  'background-color': '#007bff',
                  'text-valign': 'center',
                  'text-halign': 'center',
                  'width': '20px',
                  'height': '20px',
                }
              },
              {
                selector: 'edge[type="edge"]',
                style: {
                  'label': 'data(label)',
                  'width': 3,
                  'line-color': '#28a745',
                  'target-arrow-color': '#28a745',
                  'target-arrow-shape': 'triangle'
                }
              }
            ],
            layout: {
              name: 'cose',
              rows: 1
            }
          });
        });
    
        return { containerRef };
      },
      template: '<div ref="containerRef" class="network"></div>'
    };
    
    createApp(App).mount('#app');
    	
    	
    })

    This uses the Cytoscape JavaScript library to display the knowledge Graph data from Neo4j. 

    node animation

    From here you can build a knowledge Graph based on your own data, then interact with it from Appsmith, and integrate with other APIs and Databases. 

Conclusion

Knowledge Graphs are a powerful tool for exploring your data, and they can be more effective for RAG (retrieval-augmented generation) that traditional databases. Neo4j's makes it easy to self-host your own knowledge graph locally, or in the same VPC as your Appsmith server. This enables you to integrate with any API or database from Appsmith and programmatically create graphs, or query the graph for RAG to improve LLM responses.