Find answers from the community

Updated 5 months ago

Hello. I am trying to use

At a glance
Hello. I am trying to use PropertyGraphIndex with SimplePropertyGraphStore to store data from netwokx graph. The nodes and edges from the networkx graph are upserted into the graph store as EntityNode and Relation instances. I can get data from the store using methods like graph_store.get using properties or ids. But I don't understand how to query the index. The index is created using index = PropertyGraphIndex.from_existing(property_graph_store=graph_store).

Then, the query engine is created as
Plain Text
llm_synonym_retriever = LLMSynonymRetriever(
    index.property_graph_store,
    llm=llm,
    include_text=False,
)
vector_context_retriever = VectorContextRetriever(
    index.property_graph_store,
    embed_model=HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5"),
    include_text=False,
) 
query_engine = index.as_query_engine(
    sub_retrievers=[
        vector_context_retriever,
        llm_synonym_retriever,
    ],
    llm=llm,
)
# llm is Ollama(model="llama3")


The problem is that query_engine.query() always returns empty response.
Plain Text
response = query_engine.query("What is the email address of user Fname Lname?")
L
a
11 comments
Are you saving and loading the vector store though?

Without the vector store, you are relying on the synoym/keyword retrieval, which isn't always great
which vector store should i use? vetor store wants nodes to be of type BaseNode, while graph nodes are EntityNode inheriting from pydantic model
The types all get handled under the hood -- use whichever vector store you want?

The default is SimpleVectorStore, it was probably used when you first created the index, but it seems like you either didn't save it or didn't load it
Plain Text
llm = Ollama(
    model="llama3",
    request_timeout=300.0,
    additional_kwargs={
        "trust_remote_code": True,
        "generate_kwargs": {"temperature": 0.0, "do_sample": False},
    },
)
embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5")

llm.context_window = 4096
Settings.llm = llm
Settings.chunk_size = 1024
Settings.embed_model = embed_model

vector_store = SimpleVectorStore()
storage_context = StorageContext.from_defaults(vector_store=vector_store)
storage_context.vector_stores["default"] = vector_store

user = {
    "id": "user_1",
    "name": "Stepan Ivan",
    "email": "user@example.com",
    "type": "user",
}

market = {
    "id": "market_1",
    "name": "Canada",
    "type": "market",
}

relation = Relation(
    label="market_member", source_id=user["id"], target_id=market["id"], properties={}
)

graph_store = SimplePropertyGraphStore()
graph_store.upsert_nodes(
    [
        EntityNode(label=user["type"], name=user["id"], properties=user),
        EntityNode(label=market["type"], name=market["id"], properties=market),
    ]
)
graph_store.upsert_relations([relation])

index = PropertyGraphIndex.from_existing(
    llm=llm,
    property_graph_store=graph_store,
    storage_context=storage_context,
    embed_kg_nodes=True,
    show_progress=True,
)

llm_synonym_retriever = LLMSynonymRetriever(
    index.property_graph_store,
    llm=llm,
    include_text=False,
)

vector_context_retriever = VectorContextRetriever(
    graph_store=index.property_graph_store,
    embed_model=embed_model,
    vector_store=index.vector_store,
    include_text=False,
)

query_engine = index.as_query_engine(
    sub_retrievers=[
        vector_context_retriever,
        llm_synonym_retriever,
    ],
    llm=llm,
)
Plain Text
nodes = graph_store.get(properties={"email": "user@example.com"})
this works as expected
Plain Text
query_engine.query("What is Stepan's last name?")
this doesn't work
the model either returns something like "I'm happy to help! However, I don't see any information about a person named Stepan. The context only mentions user_1, market_member, and market_1, but no mention of Stepan or their last name. Therefore, I cannot provide an answer to the query."
or, returns empty response if I upsert thousands of nodes
You can check what the retriever is retrieving

retriever.retrieve("query")

Or check the source nodes on the response

Plain Text
response = query_engine.query(...)
for node in response.source_nodes:
  print(node.text)
retriever node user_1 -> market_member -> market_1 and response node user_1 -> market_member -> market_1. It looks like entity nodes are not quired at all?
The strange thing is that when I dump the information about nodes into a plain text file - one sentence that describes users' attributes like name, id, email, etc and load using SimpleDirectoryReader, then I get almost correct response. The model is able to determine user's email by user name. But it works because SimpleDirectoryReader creates documents and nodes with relations where each node is a property. For example User -> Has email -> Email, which I think is wrong because I would expect to get one node with all the properties and then another node lets say Market with relation User -> Member Of -> Market.
Add a reply
Sign up and join the conversation on Discord