FalkorDB Property Graph Index
FalkorDB is a production-grade graph database, capable of storing a property graph, performing vector search, filtering, and more.
The easiest way to get started is with a cloud-hosted instance using FalkorDB Cloud
For this notebook, we will instead cover how to run the database locally with docker.
If you already have an existing graph, please skip to the end of this notebook.
%pip install llama-index llama-index-graph-stores-falkordb
Docker Setup
Section titled βDocker SetupβTo launch FalkorDB locally, first ensure you have docker installed. Then, you can launch the database with the following docker command
docker run \ -p 3000:3000 -p 6379:6379 \ -v $PWD/data:/data \ falkordb/falkordb:latest
From here, you can open the db at http://localhost:3000/. On this page, you will be asked to sign in.
After this, you are ready to create your first property graph!
Env Setup
Section titled βEnv SetupβWe need just a few environment setups to get started.
import os
os.environ["OPENAI_API_KEY"] = "sk-proj-..."
!mkdir -p 'data/paul_graham/'!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/docs/examples/data/paul_graham/paul_graham_essay.txt' -O 'data/paul_graham/paul_graham_essay.txt'
import nest_asyncio
nest_asyncio.apply()
from llama_index.core import SimpleDirectoryReader
documents = SimpleDirectoryReader("./data/paul_graham/").load_data()
Index Construction
Section titled βIndex Constructionβfrom llama_index.graph_stores.falkordb import FalkorDBPropertyGraphStore
# Note: used to be `FalkorDBPGStore`graph_store = FalkorDBPropertyGraphStore( url="falkor://localhost:6379",)
from llama_index.core import PropertyGraphIndexfrom llama_index.embeddings.openai import OpenAIEmbeddingfrom llama_index.llms.openai import OpenAIfrom llama_index.core.indices.property_graph import SchemaLLMPathExtractor
index = PropertyGraphIndex.from_documents( documents, embed_model=OpenAIEmbedding(model_name="text-embedding-3-small"), kg_extractors=[ SchemaLLMPathExtractor( llm=OpenAI(model="gpt-3.5-turbo", temperature=0.0) ) ], property_graph_store=graph_store, show_progress=True,)
Parsing nodes: 100%|ββββββββββ| 1/1 [00:00<00:00, 21.63it/s]Extracting paths from text with schema: 100%|ββββββββββ| 22/22 [01:06<00:00, 3.02s/it]Generating embeddings: 100%|ββββββββββ| 1/1 [00:00<00:00, 1.06it/s]Generating embeddings: 100%|ββββββββββ| 1/1 [00:00<00:00, 1.89it/s]
Now that the graph is created, we can explore it in the UI by visting http://localhost:3000/.
The easiest way to see the entire graph is to use a cypher command like "match n=() return n"
at the top.
To delete an entire graph, a useful command is "match n=() detach delete n"
.
Querying and Retrieval
Section titled βQuerying and Retrievalβretriever = index.as_retriever( include_text=False, # include source text in returned nodes, default True)
nodes = retriever.retrieve("What happened at Interleaf and Viaweb?")
for node in nodes: print(node.text)
Interleaf -> Got crushed by -> Moore's lawInterleaf -> Made -> Scripting languageInterleaf -> Had -> Smart peopleInterleaf -> Inspired by -> EmacsInterleaf -> Had -> Few years to liveInterleaf -> Made -> SoftwareInterleaf -> Had done -> Something boldInterleaf -> Added -> Scripting languageInterleaf -> Built -> Impressive technologyInterleaf -> Was -> CompanyViaweb -> Was -> ProfitableViaweb -> Was -> Growing rapidlyViaweb -> Suggested -> HospitalIdea -> Was clear from -> ExperienceIdea -> Would have to be embodied as -> CompanyPainting department -> Seemed to be -> Rigorous
query_engine = index.as_query_engine(include_text=True)
response = query_engine.query("What happened at Interleaf and Viaweb?")
print(str(response))
Interleaf had smart people and built impressive technology but got crushed by Moore's Law. Viaweb was profitable and growing rapidly.
Loading from an existing Graph
Section titled βLoading from an existing GraphβIf you have an existing graph (either created with LlamaIndex or otherwise), we can connect to and use it!
NOTE: If your graph was created outside of LlamaIndex, the most useful retrievers will be text to cypher or cypher templates. Other retrievers rely on properties that LlamaIndex inserts.
from llama_index.graph_stores.falkordb import FalkorDBPropertyGraphStorefrom llama_index.core import PropertyGraphIndexfrom llama_index.embeddings.openai import OpenAIEmbeddingfrom llama_index.llms.openai import OpenAI
graph_store = FalkorDBPropertyGraphStore( url="falkor://localhost:6379",)
index = PropertyGraphIndex.from_existing( property_graph_store=graph_store, llm=OpenAI(model="gpt-3.5-turbo", temperature=0.3), embed_model=OpenAIEmbedding(model_name="text-embedding-3-small"),)
From here, we can still insert more documents!
from llama_index.core import Document
document = Document(text="LlamaIndex is great!")
index.insert(document)
nodes = index.as_retriever(include_text=False).retrieve("LlamaIndex")
print(nodes[0].text)
Llamaindex -> Is -> Great
For full details on construction, retrieval, querying of a property graph, see the full docs page.