|
|
|
""" |
|
้็จๅพๅญๅจๆต่ฏ็จๅบ |
|
|
|
่ฏฅ็จๅบๆ นๆฎ.envไธญ็LIGHTRAG_GRAPH_STORAGE้
็ฝฎ้ๆฉไฝฟ็จ็ๅพๅญๅจ็ฑปๅ๏ผ |
|
ๅนถๅฏนๅ
ถ่ฟ่กๅบๆฌๆไฝๅ้ซ็บงๆไฝ็ๆต่ฏใ |
|
|
|
ๆฏๆ็ๅพๅญๅจ็ฑปๅๅ
ๆฌ๏ผ |
|
- NetworkXStorage |
|
- Neo4JStorage |
|
- MongoDBStorage |
|
- PGGraphStorage |
|
- MemgraphStorage |
|
""" |
|
|
|
import asyncio |
|
import os |
|
import sys |
|
import importlib |
|
import numpy as np |
|
from dotenv import load_dotenv |
|
from ascii_colors import ASCIIColors |
|
|
|
|
|
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) |
|
|
|
from lightrag.types import KnowledgeGraph |
|
from lightrag.kg import ( |
|
STORAGE_IMPLEMENTATIONS, |
|
STORAGE_ENV_REQUIREMENTS, |
|
STORAGES, |
|
verify_storage_implementation, |
|
) |
|
from lightrag.kg.shared_storage import initialize_share_data |
|
from lightrag.constants import GRAPH_FIELD_SEP |
|
|
|
|
|
|
|
async def mock_embedding_func(texts): |
|
return np.random.rand(len(texts), 10) |
|
|
|
|
|
def check_env_file(): |
|
""" |
|
ๆฃๆฅ.envๆไปถๆฏๅฆๅญๅจ๏ผๅฆๆไธๅญๅจๅๅๅบ่ญฆๅ |
|
่ฟๅTrue่กจ็คบๅบ่ฏฅ็ปง็ปญๆง่ก๏ผFalse่กจ็คบๅบ่ฏฅ้ๅบ |
|
""" |
|
if not os.path.exists(".env"): |
|
warning_msg = "่ญฆๅ: ๅฝๅ็ฎๅฝไธญๆฒกๆๆพๅฐ.envๆไปถ๏ผ่ฟๅฏ่ฝไผๅฝฑๅๅญๅจ้
็ฝฎ็ๅ ่ฝฝใ" |
|
ASCIIColors.yellow(warning_msg) |
|
|
|
|
|
if sys.stdin.isatty(): |
|
response = input("ๆฏๅฆ็ปง็ปญๆง่ก? (yes/no): ") |
|
if response.lower() != "yes": |
|
ASCIIColors.red("ๆต่ฏ็จๅบๅทฒๅๆถ") |
|
return False |
|
return True |
|
|
|
|
|
async def initialize_graph_storage(): |
|
""" |
|
ๆ นๆฎ็ฏๅขๅ้ๅๅงๅ็ธๅบ็ๅพๅญๅจๅฎไพ |
|
่ฟๅๅๅงๅ็ๅญๅจๅฎไพ |
|
""" |
|
|
|
graph_storage_type = os.getenv("LIGHTRAG_GRAPH_STORAGE", "NetworkXStorage") |
|
|
|
|
|
try: |
|
verify_storage_implementation("GRAPH_STORAGE", graph_storage_type) |
|
except ValueError as e: |
|
ASCIIColors.red(f"้่ฏฏ: {str(e)}") |
|
ASCIIColors.yellow( |
|
f"ๆฏๆ็ๅพๅญๅจ็ฑปๅ: {', '.join(STORAGE_IMPLEMENTATIONS['GRAPH_STORAGE']['implementations'])}" |
|
) |
|
return None |
|
|
|
|
|
required_env_vars = STORAGE_ENV_REQUIREMENTS.get(graph_storage_type, []) |
|
missing_env_vars = [var for var in required_env_vars if not os.getenv(var)] |
|
|
|
if missing_env_vars: |
|
ASCIIColors.red( |
|
f"้่ฏฏ: {graph_storage_type} ้่ฆไปฅไธ็ฏๅขๅ้๏ผไฝๆช่ฎพ็ฝฎ: {', '.join(missing_env_vars)}" |
|
) |
|
return None |
|
|
|
|
|
module_path = STORAGES.get(graph_storage_type) |
|
if not module_path: |
|
ASCIIColors.red(f"้่ฏฏ: ๆชๆพๅฐ {graph_storage_type} ็ๆจกๅ่ทฏๅพ") |
|
return None |
|
|
|
try: |
|
module = importlib.import_module(module_path, package="lightrag") |
|
storage_class = getattr(module, graph_storage_type) |
|
except (ImportError, AttributeError) as e: |
|
ASCIIColors.red(f"้่ฏฏ: ๅฏผๅ
ฅ {graph_storage_type} ๅคฑ่ดฅ: {str(e)}") |
|
return None |
|
|
|
|
|
global_config = { |
|
"embedding_batch_num": 10, |
|
"vector_db_storage_cls_kwargs": { |
|
"cosine_better_than_threshold": 0.5 |
|
}, |
|
"working_dir": os.environ.get("WORKING_DIR", "./rag_storage"), |
|
} |
|
|
|
|
|
if graph_storage_type == "NetworkXStorage": |
|
initialize_share_data() |
|
|
|
try: |
|
storage = storage_class( |
|
namespace="test_graph", |
|
global_config=global_config, |
|
embedding_func=mock_embedding_func, |
|
) |
|
|
|
|
|
await storage.initialize() |
|
return storage |
|
except Exception as e: |
|
ASCIIColors.red(f"้่ฏฏ: ๅๅงๅ {graph_storage_type} ๅคฑ่ดฅ: {str(e)}") |
|
return None |
|
|
|
|
|
async def test_graph_basic(storage): |
|
""" |
|
ๆต่ฏๅพๆฐๆฎๅบ็ๅบๆฌๆไฝ: |
|
1. ไฝฟ็จ upsert_node ๆๅ
ฅไธคไธช่็น |
|
2. ไฝฟ็จ upsert_edge ๆๅ
ฅไธๆก่ฟๆฅไธคไธช่็น็่พน |
|
3. ไฝฟ็จ get_node ่ฏปๅไธไธช่็น |
|
4. ไฝฟ็จ get_edge ่ฏปๅไธๆก่พน |
|
""" |
|
try: |
|
|
|
node1_id = "ไบบๅทฅๆบ่ฝ" |
|
node1_data = { |
|
"entity_id": node1_id, |
|
"description": "ไบบๅทฅๆบ่ฝๆฏ่ฎก็ฎๆบ็งๅญฆ็ไธไธชๅๆฏ๏ผๅฎไผๅพไบ่งฃๆบ่ฝ็ๅฎ่ดจ๏ผๅนถ็ไบงๅบไธ็งๆฐ็่ฝไปฅไบบ็ฑปๆบ่ฝ็ธไผผ็ๆนๅผๅๅบๅๅบ็ๆบ่ฝๆบๅจใ", |
|
"keywords": "AI,ๆบๅจๅญฆไน ,ๆทฑๅบฆๅญฆไน ", |
|
"entity_type": "ๆๆฏ้ขๅ", |
|
} |
|
print(f"ๆๅ
ฅ่็น1: {node1_id}") |
|
await storage.upsert_node(node1_id, node1_data) |
|
|
|
|
|
node2_id = "ๆบๅจๅญฆไน " |
|
node2_data = { |
|
"entity_id": node2_id, |
|
"description": "ๆบๅจๅญฆไน ๆฏไบบๅทฅๆบ่ฝ็ไธไธชๅๆฏ๏ผๅฎไฝฟ็จ็ป่ฎกๅญฆๆนๆณ่ฎฉ่ฎก็ฎๆบ็ณป็ปๅจไธ่ขซๆ็กฎ็ผ็จ็ๆ
ๅตไธไน่ฝๅคๅญฆไน ใ", |
|
"keywords": "็็ฃๅญฆไน ,ๆ ็็ฃๅญฆไน ,ๅผบๅๅญฆไน ", |
|
"entity_type": "ๆๆฏ้ขๅ", |
|
} |
|
print(f"ๆๅ
ฅ่็น2: {node2_id}") |
|
await storage.upsert_node(node2_id, node2_data) |
|
|
|
|
|
edge_data = { |
|
"relationship": "ๅ
ๅซ", |
|
"weight": 1.0, |
|
"description": "ไบบๅทฅๆบ่ฝ้ขๅๅ
ๅซๆบๅจๅญฆไน ่ฟไธชๅญ้ขๅ", |
|
} |
|
print(f"ๆๅ
ฅ่พน: {node1_id} -> {node2_id}") |
|
await storage.upsert_edge(node1_id, node2_id, edge_data) |
|
|
|
|
|
print(f"่ฏปๅ่็นๅฑๆง: {node1_id}") |
|
node1_props = await storage.get_node(node1_id) |
|
if node1_props: |
|
print(f"ๆๅ่ฏปๅ่็นๅฑๆง: {node1_id}") |
|
print(f"่็นๆ่ฟฐ: {node1_props.get('description', 'ๆ ๆ่ฟฐ')}") |
|
print(f"่็น็ฑปๅ: {node1_props.get('entity_type', 'ๆ ็ฑปๅ')}") |
|
print(f"่็นๅ
ณ้ฎ่ฏ: {node1_props.get('keywords', 'ๆ ๅ
ณ้ฎ่ฏ')}") |
|
|
|
assert ( |
|
node1_props.get("entity_id") == node1_id |
|
), f"่็นIDไธๅน้
: ๆๆ {node1_id}, ๅฎ้
{node1_props.get('entity_id')}" |
|
assert ( |
|
node1_props.get("description") == node1_data["description"] |
|
), "่็นๆ่ฟฐไธๅน้
" |
|
assert ( |
|
node1_props.get("entity_type") == node1_data["entity_type"] |
|
), "่็น็ฑปๅไธๅน้
" |
|
else: |
|
print(f"่ฏปๅ่็นๅฑๆงๅคฑ่ดฅ: {node1_id}") |
|
assert False, f"ๆช่ฝ่ฏปๅ่็นๅฑๆง: {node1_id}" |
|
|
|
|
|
print(f"่ฏปๅ่พนๅฑๆง: {node1_id} -> {node2_id}") |
|
edge_props = await storage.get_edge(node1_id, node2_id) |
|
if edge_props: |
|
print(f"ๆๅ่ฏปๅ่พนๅฑๆง: {node1_id} -> {node2_id}") |
|
print(f"่พนๅ
ณ็ณป: {edge_props.get('relationship', 'ๆ ๅ
ณ็ณป')}") |
|
print(f"่พนๆ่ฟฐ: {edge_props.get('description', 'ๆ ๆ่ฟฐ')}") |
|
print(f"่พนๆ้: {edge_props.get('weight', 'ๆ ๆ้')}") |
|
|
|
assert ( |
|
edge_props.get("relationship") == edge_data["relationship"] |
|
), "่พนๅ
ณ็ณปไธๅน้
" |
|
assert ( |
|
edge_props.get("description") == edge_data["description"] |
|
), "่พนๆ่ฟฐไธๅน้
" |
|
assert edge_props.get("weight") == edge_data["weight"], "่พนๆ้ไธๅน้
" |
|
else: |
|
print(f"่ฏปๅ่พนๅฑๆงๅคฑ่ดฅ: {node1_id} -> {node2_id}") |
|
assert False, f"ๆช่ฝ่ฏปๅ่พนๅฑๆง: {node1_id} -> {node2_id}" |
|
|
|
|
|
print(f"่ฏปๅๅๅ่พนๅฑๆง: {node2_id} -> {node1_id}") |
|
reverse_edge_props = await storage.get_edge(node2_id, node1_id) |
|
if reverse_edge_props: |
|
print(f"ๆๅ่ฏปๅๅๅ่พนๅฑๆง: {node2_id} -> {node1_id}") |
|
print(f"ๅๅ่พนๅ
ณ็ณป: {reverse_edge_props.get('relationship', 'ๆ ๅ
ณ็ณป')}") |
|
print(f"ๅๅ่พนๆ่ฟฐ: {reverse_edge_props.get('description', 'ๆ ๆ่ฟฐ')}") |
|
print(f"ๅๅ่พนๆ้: {reverse_edge_props.get('weight', 'ๆ ๆ้')}") |
|
|
|
assert ( |
|
edge_props == reverse_edge_props |
|
), "ๆญฃๅๅๅๅ่พนๅฑๆงไธไธ่ด๏ผๆ ๅๅพ็นๆง้ช่ฏๅคฑ่ดฅ" |
|
print("ๆ ๅๅพ็นๆง้ช่ฏๆๅ๏ผๆญฃๅๅๅๅ่พนๅฑๆงไธ่ด") |
|
else: |
|
print(f"่ฏปๅๅๅ่พนๅฑๆงๅคฑ่ดฅ: {node2_id} -> {node1_id}") |
|
assert ( |
|
False |
|
), f"ๆช่ฝ่ฏปๅๅๅ่พนๅฑๆง: {node2_id} -> {node1_id}๏ผๆ ๅๅพ็นๆง้ช่ฏๅคฑ่ดฅ" |
|
|
|
print("ๅบๆฌๆต่ฏๅฎๆ๏ผๆฐๆฎๅทฒไฟ็ๅจๆฐๆฎๅบไธญ") |
|
return True |
|
|
|
except Exception as e: |
|
ASCIIColors.red(f"ๆต่ฏ่ฟ็จไธญๅ็้่ฏฏ: {str(e)}") |
|
return False |
|
|
|
|
|
async def test_graph_advanced(storage): |
|
""" |
|
ๆต่ฏๅพๆฐๆฎๅบ็้ซ็บงๆไฝ: |
|
1. ไฝฟ็จ node_degree ่ทๅ่็น็ๅบฆๆฐ |
|
2. ไฝฟ็จ edge_degree ่ทๅ่พน็ๅบฆๆฐ |
|
3. ไฝฟ็จ get_node_edges ่ทๅ่็น็ๆๆ่พน |
|
4. ไฝฟ็จ get_all_labels ่ทๅๆๆๆ ็ญพ |
|
5. ไฝฟ็จ get_knowledge_graph ่ทๅ็ฅ่ฏๅพ่ฐฑ |
|
6. ไฝฟ็จ delete_node ๅ ้ค่็น |
|
7. ไฝฟ็จ remove_nodes ๆน้ๅ ้ค่็น |
|
8. ไฝฟ็จ remove_edges ๅ ้ค่พน |
|
9. ไฝฟ็จ drop ๆธ
็ๆฐๆฎ |
|
""" |
|
try: |
|
|
|
|
|
node1_id = "ไบบๅทฅๆบ่ฝ" |
|
node1_data = { |
|
"entity_id": node1_id, |
|
"description": "ไบบๅทฅๆบ่ฝๆฏ่ฎก็ฎๆบ็งๅญฆ็ไธไธชๅๆฏ๏ผๅฎไผๅพไบ่งฃๆบ่ฝ็ๅฎ่ดจ๏ผๅนถ็ไบงๅบไธ็งๆฐ็่ฝไปฅไบบ็ฑปๆบ่ฝ็ธไผผ็ๆนๅผๅๅบๅๅบ็ๆบ่ฝๆบๅจใ", |
|
"keywords": "AI,ๆบๅจๅญฆไน ,ๆทฑๅบฆๅญฆไน ", |
|
"entity_type": "ๆๆฏ้ขๅ", |
|
} |
|
print(f"ๆๅ
ฅ่็น1: {node1_id}") |
|
await storage.upsert_node(node1_id, node1_data) |
|
|
|
|
|
node2_id = "ๆบๅจๅญฆไน " |
|
node2_data = { |
|
"entity_id": node2_id, |
|
"description": "ๆบๅจๅญฆไน ๆฏไบบๅทฅๆบ่ฝ็ไธไธชๅๆฏ๏ผๅฎไฝฟ็จ็ป่ฎกๅญฆๆนๆณ่ฎฉ่ฎก็ฎๆบ็ณป็ปๅจไธ่ขซๆ็กฎ็ผ็จ็ๆ
ๅตไธไน่ฝๅคๅญฆไน ใ", |
|
"keywords": "็็ฃๅญฆไน ,ๆ ็็ฃๅญฆไน ,ๅผบๅๅญฆไน ", |
|
"entity_type": "ๆๆฏ้ขๅ", |
|
} |
|
print(f"ๆๅ
ฅ่็น2: {node2_id}") |
|
await storage.upsert_node(node2_id, node2_data) |
|
|
|
|
|
node3_id = "ๆทฑๅบฆๅญฆไน " |
|
node3_data = { |
|
"entity_id": node3_id, |
|
"description": "ๆทฑๅบฆๅญฆไน ๆฏๆบๅจๅญฆไน ็ไธไธชๅๆฏ๏ผๅฎไฝฟ็จๅคๅฑ็ฅ็ป็ฝ็ปๆฅๆจกๆไบบ่็ๅญฆไน ่ฟ็จใ", |
|
"keywords": "็ฅ็ป็ฝ็ป,CNN,RNN", |
|
"entity_type": "ๆๆฏ้ขๅ", |
|
} |
|
print(f"ๆๅ
ฅ่็น3: {node3_id}") |
|
await storage.upsert_node(node3_id, node3_data) |
|
|
|
|
|
edge1_data = { |
|
"relationship": "ๅ
ๅซ", |
|
"weight": 1.0, |
|
"description": "ไบบๅทฅๆบ่ฝ้ขๅๅ
ๅซๆบๅจๅญฆไน ่ฟไธชๅญ้ขๅ", |
|
} |
|
print(f"ๆๅ
ฅ่พน1: {node1_id} -> {node2_id}") |
|
await storage.upsert_edge(node1_id, node2_id, edge1_data) |
|
|
|
|
|
edge2_data = { |
|
"relationship": "ๅ
ๅซ", |
|
"weight": 1.0, |
|
"description": "ๆบๅจๅญฆไน ้ขๅๅ
ๅซๆทฑๅบฆๅญฆไน ่ฟไธชๅญ้ขๅ", |
|
} |
|
print(f"ๆๅ
ฅ่พน2: {node2_id} -> {node3_id}") |
|
await storage.upsert_edge(node2_id, node3_id, edge2_data) |
|
|
|
|
|
print(f"== ๆต่ฏ node_degree: {node1_id}") |
|
node1_degree = await storage.node_degree(node1_id) |
|
print(f"่็น {node1_id} ็ๅบฆๆฐ: {node1_degree}") |
|
assert node1_degree == 1, f"่็น {node1_id} ็ๅบฆๆฐๅบไธบ1๏ผๅฎ้
ไธบ {node1_degree}" |
|
|
|
|
|
print("== ๆต่ฏๆๆ่็น็ๅบฆๆฐ") |
|
node2_degree = await storage.node_degree(node2_id) |
|
node3_degree = await storage.node_degree(node3_id) |
|
print(f"่็น {node2_id} ็ๅบฆๆฐ: {node2_degree}") |
|
print(f"่็น {node3_id} ็ๅบฆๆฐ: {node3_degree}") |
|
assert node2_degree == 2, f"่็น {node2_id} ็ๅบฆๆฐๅบไธบ2๏ผๅฎ้
ไธบ {node2_degree}" |
|
assert node3_degree == 1, f"่็น {node3_id} ็ๅบฆๆฐๅบไธบ1๏ผๅฎ้
ไธบ {node3_degree}" |
|
|
|
|
|
print(f"== ๆต่ฏ edge_degree: {node1_id} -> {node2_id}") |
|
edge_degree = await storage.edge_degree(node1_id, node2_id) |
|
print(f"่พน {node1_id} -> {node2_id} ็ๅบฆๆฐ: {edge_degree}") |
|
assert ( |
|
edge_degree == 3 |
|
), f"่พน {node1_id} -> {node2_id} ็ๅบฆๆฐๅบไธบ3๏ผๅฎ้
ไธบ {edge_degree}" |
|
|
|
|
|
print(f"== ๆต่ฏๅๅ่พน็ๅบฆๆฐ: {node2_id} -> {node1_id}") |
|
reverse_edge_degree = await storage.edge_degree(node2_id, node1_id) |
|
print(f"ๅๅ่พน {node2_id} -> {node1_id} ็ๅบฆๆฐ: {reverse_edge_degree}") |
|
assert ( |
|
edge_degree == reverse_edge_degree |
|
), "ๆญฃๅ่พนๅๅๅ่พน็ๅบฆๆฐไธไธ่ด๏ผๆ ๅๅพ็นๆง้ช่ฏๅคฑ่ดฅ" |
|
print("ๆ ๅๅพ็นๆง้ช่ฏๆๅ๏ผๆญฃๅ่พนๅๅๅ่พน็ๅบฆๆฐไธ่ด") |
|
|
|
|
|
print(f"== ๆต่ฏ get_node_edges: {node2_id}") |
|
node2_edges = await storage.get_node_edges(node2_id) |
|
print(f"่็น {node2_id} ็ๆๆ่พน: {node2_edges}") |
|
assert ( |
|
len(node2_edges) == 2 |
|
), f"่็น {node2_id} ๅบๆ2ๆก่พน๏ผๅฎ้
ๆ {len(node2_edges)}" |
|
|
|
|
|
print("== ้ช่ฏ่็น่พน็ๆ ๅๅพ็นๆง") |
|
|
|
has_connection_with_node1 = False |
|
has_connection_with_node3 = False |
|
for edge in node2_edges: |
|
|
|
if (edge[0] == node1_id and edge[1] == node2_id) or ( |
|
edge[0] == node2_id and edge[1] == node1_id |
|
): |
|
has_connection_with_node1 = True |
|
|
|
if (edge[0] == node2_id and edge[1] == node3_id) or ( |
|
edge[0] == node3_id and edge[1] == node2_id |
|
): |
|
has_connection_with_node3 = True |
|
|
|
assert ( |
|
has_connection_with_node1 |
|
), f"่็น {node2_id} ็่พนๅ่กจไธญๅบๅ
ๅซไธ {node1_id} ็่ฟๆฅ" |
|
assert ( |
|
has_connection_with_node3 |
|
), f"่็น {node2_id} ็่พนๅ่กจไธญๅบๅ
ๅซไธ {node3_id} ็่ฟๆฅ" |
|
print(f"ๆ ๅๅพ็นๆง้ช่ฏๆๅ๏ผ่็น {node2_id} ็่พนๅ่กจๅ
ๅซๆๆ็ธๅ
ณ็่พน") |
|
|
|
|
|
print("== ๆต่ฏ get_all_labels") |
|
all_labels = await storage.get_all_labels() |
|
print(f"ๆๆๆ ็ญพ: {all_labels}") |
|
assert len(all_labels) == 3, f"ๅบๆ3ไธชๆ ็ญพ๏ผๅฎ้
ๆ {len(all_labels)}" |
|
assert node1_id in all_labels, f"{node1_id} ๅบๅจๆ ็ญพๅ่กจไธญ" |
|
assert node2_id in all_labels, f"{node2_id} ๅบๅจๆ ็ญพๅ่กจไธญ" |
|
assert node3_id in all_labels, f"{node3_id} ๅบๅจๆ ็ญพๅ่กจไธญ" |
|
|
|
|
|
print("== ๆต่ฏ get_knowledge_graph") |
|
kg = await storage.get_knowledge_graph("*", max_depth=2, max_nodes=10) |
|
print(f"็ฅ่ฏๅพ่ฐฑ่็นๆฐ: {len(kg.nodes)}") |
|
print(f"็ฅ่ฏๅพ่ฐฑ่พนๆฐ: {len(kg.edges)}") |
|
assert isinstance(kg, KnowledgeGraph), "่ฟๅ็ปๆๅบไธบ KnowledgeGraph ็ฑปๅ" |
|
assert len(kg.nodes) == 3, f"็ฅ่ฏๅพ่ฐฑๅบๆ3ไธช่็น๏ผๅฎ้
ๆ {len(kg.nodes)}" |
|
assert len(kg.edges) == 2, f"็ฅ่ฏๅพ่ฐฑๅบๆ2ๆก่พน๏ผๅฎ้
ๆ {len(kg.edges)}" |
|
|
|
|
|
print(f"== ๆต่ฏ delete_node: {node3_id}") |
|
await storage.delete_node(node3_id) |
|
node3_props = await storage.get_node(node3_id) |
|
print(f"ๅ ้คๅๆฅ่ฏข่็นๅฑๆง {node3_id}: {node3_props}") |
|
assert node3_props is None, f"่็น {node3_id} ๅบๅทฒ่ขซๅ ้ค" |
|
|
|
|
|
await storage.upsert_node(node3_id, node3_data) |
|
await storage.upsert_edge(node2_id, node3_id, edge2_data) |
|
|
|
|
|
print(f"== ๆต่ฏ remove_edges: {node2_id} -> {node3_id}") |
|
await storage.remove_edges([(node2_id, node3_id)]) |
|
edge_props = await storage.get_edge(node2_id, node3_id) |
|
print(f"ๅ ้คๅๆฅ่ฏข่พนๅฑๆง {node2_id} -> {node3_id}: {edge_props}") |
|
assert edge_props is None, f"่พน {node2_id} -> {node3_id} ๅบๅทฒ่ขซๅ ้ค" |
|
|
|
|
|
print(f"== ้ช่ฏๅ ้ค่พน็ๆ ๅๅพ็นๆง: {node3_id} -> {node2_id}") |
|
reverse_edge_props = await storage.get_edge(node3_id, node2_id) |
|
print(f"ๅ ้คๅๆฅ่ฏขๅๅ่พนๅฑๆง {node3_id} -> {node2_id}: {reverse_edge_props}") |
|
assert ( |
|
reverse_edge_props is None |
|
), f"ๅๅ่พน {node3_id} -> {node2_id} ไนๅบ่ขซๅ ้ค๏ผๆ ๅๅพ็นๆง้ช่ฏๅคฑ่ดฅ" |
|
print("ๆ ๅๅพ็นๆง้ช่ฏๆๅ๏ผๅ ้คไธไธชๆนๅ็่พนๅ๏ผๅๅ่พนไน่ขซๅ ้ค") |
|
|
|
|
|
print(f"== ๆต่ฏ remove_nodes: [{node2_id}, {node3_id}]") |
|
await storage.remove_nodes([node2_id, node3_id]) |
|
node2_props = await storage.get_node(node2_id) |
|
node3_props = await storage.get_node(node3_id) |
|
print(f"ๅ ้คๅๆฅ่ฏข่็นๅฑๆง {node2_id}: {node2_props}") |
|
print(f"ๅ ้คๅๆฅ่ฏข่็นๅฑๆง {node3_id}: {node3_props}") |
|
assert node2_props is None, f"่็น {node2_id} ๅบๅทฒ่ขซๅ ้ค" |
|
assert node3_props is None, f"่็น {node3_id} ๅบๅทฒ่ขซๅ ้ค" |
|
|
|
print("\n้ซ็บงๆต่ฏๅฎๆ") |
|
return True |
|
|
|
except Exception as e: |
|
ASCIIColors.red(f"ๆต่ฏ่ฟ็จไธญๅ็้่ฏฏ: {str(e)}") |
|
return False |
|
|
|
|
|
async def test_graph_batch_operations(storage): |
|
""" |
|
ๆต่ฏๅพๆฐๆฎๅบ็ๆน้ๆไฝ: |
|
1. ไฝฟ็จ get_nodes_batch ๆน้่ทๅๅคไธช่็น็ๅฑๆง |
|
2. ไฝฟ็จ node_degrees_batch ๆน้่ทๅๅคไธช่็น็ๅบฆๆฐ |
|
3. ไฝฟ็จ edge_degrees_batch ๆน้่ทๅๅคไธช่พน็ๅบฆๆฐ |
|
4. ไฝฟ็จ get_edges_batch ๆน้่ทๅๅคไธช่พน็ๅฑๆง |
|
5. ไฝฟ็จ get_nodes_edges_batch ๆน้่ทๅๅคไธช่็น็ๆๆ่พน |
|
""" |
|
try: |
|
chunk1_id = "1" |
|
chunk2_id = "2" |
|
chunk3_id = "3" |
|
|
|
|
|
node1_id = "ไบบๅทฅๆบ่ฝ" |
|
node1_data = { |
|
"entity_id": node1_id, |
|
"description": "ไบบๅทฅๆบ่ฝๆฏ่ฎก็ฎๆบ็งๅญฆ็ไธไธชๅๆฏ๏ผๅฎไผๅพไบ่งฃๆบ่ฝ็ๅฎ่ดจ๏ผๅนถ็ไบงๅบไธ็งๆฐ็่ฝไปฅไบบ็ฑปๆบ่ฝ็ธไผผ็ๆนๅผๅๅบๅๅบ็ๆบ่ฝๆบๅจใ", |
|
"keywords": "AI,ๆบๅจๅญฆไน ,ๆทฑๅบฆๅญฆไน ", |
|
"entity_type": "ๆๆฏ้ขๅ", |
|
"source_id": GRAPH_FIELD_SEP.join([chunk1_id, chunk2_id]), |
|
} |
|
print(f"ๆๅ
ฅ่็น1: {node1_id}") |
|
await storage.upsert_node(node1_id, node1_data) |
|
|
|
|
|
node2_id = "ๆบๅจๅญฆไน " |
|
node2_data = { |
|
"entity_id": node2_id, |
|
"description": "ๆบๅจๅญฆไน ๆฏไบบๅทฅๆบ่ฝ็ไธไธชๅๆฏ๏ผๅฎไฝฟ็จ็ป่ฎกๅญฆๆนๆณ่ฎฉ่ฎก็ฎๆบ็ณป็ปๅจไธ่ขซๆ็กฎ็ผ็จ็ๆ
ๅตไธไน่ฝๅคๅญฆไน ใ", |
|
"keywords": "็็ฃๅญฆไน ,ๆ ็็ฃๅญฆไน ,ๅผบๅๅญฆไน ", |
|
"entity_type": "ๆๆฏ้ขๅ", |
|
"source_id": GRAPH_FIELD_SEP.join([chunk2_id, chunk3_id]), |
|
} |
|
print(f"ๆๅ
ฅ่็น2: {node2_id}") |
|
await storage.upsert_node(node2_id, node2_data) |
|
|
|
|
|
node3_id = "ๆทฑๅบฆๅญฆไน " |
|
node3_data = { |
|
"entity_id": node3_id, |
|
"description": "ๆทฑๅบฆๅญฆไน ๆฏๆบๅจๅญฆไน ็ไธไธชๅๆฏ๏ผๅฎไฝฟ็จๅคๅฑ็ฅ็ป็ฝ็ปๆฅๆจกๆไบบ่็ๅญฆไน ่ฟ็จใ", |
|
"keywords": "็ฅ็ป็ฝ็ป,CNN,RNN", |
|
"entity_type": "ๆๆฏ้ขๅ", |
|
"source_id": GRAPH_FIELD_SEP.join([chunk3_id]), |
|
} |
|
print(f"ๆๅ
ฅ่็น3: {node3_id}") |
|
await storage.upsert_node(node3_id, node3_data) |
|
|
|
|
|
node4_id = "่ช็ถ่ฏญ่จๅค็" |
|
node4_data = { |
|
"entity_id": node4_id, |
|
"description": "่ช็ถ่ฏญ่จๅค็ๆฏไบบๅทฅๆบ่ฝ็ไธไธชๅๆฏ๏ผไธๆณจไบไฝฟ่ฎก็ฎๆบ็่งฃๅๅค็ไบบ็ฑป่ฏญ่จใ", |
|
"keywords": "NLP,ๆๆฌๅๆ,่ฏญ่จๆจกๅ", |
|
"entity_type": "ๆๆฏ้ขๅ", |
|
} |
|
print(f"ๆๅ
ฅ่็น4: {node4_id}") |
|
await storage.upsert_node(node4_id, node4_data) |
|
|
|
|
|
node5_id = "่ฎก็ฎๆบ่ง่ง" |
|
node5_data = { |
|
"entity_id": node5_id, |
|
"description": "่ฎก็ฎๆบ่ง่งๆฏไบบๅทฅๆบ่ฝ็ไธไธชๅๆฏ๏ผไธๆณจไบไฝฟ่ฎก็ฎๆบ่ฝๅคไปๅพๅๆ่ง้ขไธญ่ทๅไฟกๆฏใ", |
|
"keywords": "CV,ๅพๅ่ฏๅซ,็ฎๆ ๆฃๆต", |
|
"entity_type": "ๆๆฏ้ขๅ", |
|
} |
|
print(f"ๆๅ
ฅ่็น5: {node5_id}") |
|
await storage.upsert_node(node5_id, node5_data) |
|
|
|
|
|
edge1_data = { |
|
"relationship": "ๅ
ๅซ", |
|
"weight": 1.0, |
|
"description": "ไบบๅทฅๆบ่ฝ้ขๅๅ
ๅซๆบๅจๅญฆไน ่ฟไธชๅญ้ขๅ", |
|
"source_id": GRAPH_FIELD_SEP.join([chunk1_id, chunk2_id]), |
|
} |
|
print(f"ๆๅ
ฅ่พน1: {node1_id} -> {node2_id}") |
|
await storage.upsert_edge(node1_id, node2_id, edge1_data) |
|
|
|
|
|
edge2_data = { |
|
"relationship": "ๅ
ๅซ", |
|
"weight": 1.0, |
|
"description": "ๆบๅจๅญฆไน ้ขๅๅ
ๅซๆทฑๅบฆๅญฆไน ่ฟไธชๅญ้ขๅ", |
|
"source_id": GRAPH_FIELD_SEP.join([chunk2_id, chunk3_id]), |
|
} |
|
print(f"ๆๅ
ฅ่พน2: {node2_id} -> {node3_id}") |
|
await storage.upsert_edge(node2_id, node3_id, edge2_data) |
|
|
|
|
|
edge3_data = { |
|
"relationship": "ๅ
ๅซ", |
|
"weight": 1.0, |
|
"description": "ไบบๅทฅๆบ่ฝ้ขๅๅ
ๅซ่ช็ถ่ฏญ่จๅค็่ฟไธชๅญ้ขๅ", |
|
"source_id": GRAPH_FIELD_SEP.join([chunk3_id]), |
|
} |
|
print(f"ๆๅ
ฅ่พน3: {node1_id} -> {node4_id}") |
|
await storage.upsert_edge(node1_id, node4_id, edge3_data) |
|
|
|
|
|
edge4_data = { |
|
"relationship": "ๅ
ๅซ", |
|
"weight": 1.0, |
|
"description": "ไบบๅทฅๆบ่ฝ้ขๅๅ
ๅซ่ฎก็ฎๆบ่ง่ง่ฟไธชๅญ้ขๅ", |
|
} |
|
print(f"ๆๅ
ฅ่พน4: {node1_id} -> {node5_id}") |
|
await storage.upsert_edge(node1_id, node5_id, edge4_data) |
|
|
|
|
|
edge5_data = { |
|
"relationship": "ๅบ็จไบ", |
|
"weight": 0.8, |
|
"description": "ๆทฑๅบฆๅญฆไน ๆๆฏๅบ็จไบ่ช็ถ่ฏญ่จๅค็้ขๅ", |
|
} |
|
print(f"ๆๅ
ฅ่พน5: {node3_id} -> {node4_id}") |
|
await storage.upsert_edge(node3_id, node4_id, edge5_data) |
|
|
|
|
|
edge6_data = { |
|
"relationship": "ๅบ็จไบ", |
|
"weight": 0.8, |
|
"description": "ๆทฑๅบฆๅญฆไน ๆๆฏๅบ็จไบ่ฎก็ฎๆบ่ง่ง้ขๅ", |
|
} |
|
print(f"ๆๅ
ฅ่พน6: {node3_id} -> {node5_id}") |
|
await storage.upsert_edge(node3_id, node5_id, edge6_data) |
|
|
|
|
|
print("== ๆต่ฏ get_nodes_batch") |
|
node_ids = [node1_id, node2_id, node3_id] |
|
nodes_dict = await storage.get_nodes_batch(node_ids) |
|
print(f"ๆน้่ทๅ่็นๅฑๆง็ปๆ: {nodes_dict.keys()}") |
|
assert len(nodes_dict) == 3, f"ๅบ่ฟๅ3ไธช่็น๏ผๅฎ้
่ฟๅ {len(nodes_dict)} ไธช" |
|
assert node1_id in nodes_dict, f"{node1_id} ๅบๅจ่ฟๅ็ปๆไธญ" |
|
assert node2_id in nodes_dict, f"{node2_id} ๅบๅจ่ฟๅ็ปๆไธญ" |
|
assert node3_id in nodes_dict, f"{node3_id} ๅบๅจ่ฟๅ็ปๆไธญ" |
|
assert ( |
|
nodes_dict[node1_id]["description"] == node1_data["description"] |
|
), f"{node1_id} ๆ่ฟฐไธๅน้
" |
|
assert ( |
|
nodes_dict[node2_id]["description"] == node2_data["description"] |
|
), f"{node2_id} ๆ่ฟฐไธๅน้
" |
|
assert ( |
|
nodes_dict[node3_id]["description"] == node3_data["description"] |
|
), f"{node3_id} ๆ่ฟฐไธๅน้
" |
|
|
|
|
|
print("== ๆต่ฏ node_degrees_batch") |
|
node_degrees = await storage.node_degrees_batch(node_ids) |
|
print(f"ๆน้่ทๅ่็นๅบฆๆฐ็ปๆ: {node_degrees}") |
|
assert ( |
|
len(node_degrees) == 3 |
|
), f"ๅบ่ฟๅ3ไธช่็น็ๅบฆๆฐ๏ผๅฎ้
่ฟๅ {len(node_degrees)} ไธช" |
|
assert node1_id in node_degrees, f"{node1_id} ๅบๅจ่ฟๅ็ปๆไธญ" |
|
assert node2_id in node_degrees, f"{node2_id} ๅบๅจ่ฟๅ็ปๆไธญ" |
|
assert node3_id in node_degrees, f"{node3_id} ๅบๅจ่ฟๅ็ปๆไธญ" |
|
assert ( |
|
node_degrees[node1_id] == 3 |
|
), f"{node1_id} ๅบฆๆฐๅบไธบ3๏ผๅฎ้
ไธบ {node_degrees[node1_id]}" |
|
assert ( |
|
node_degrees[node2_id] == 2 |
|
), f"{node2_id} ๅบฆๆฐๅบไธบ2๏ผๅฎ้
ไธบ {node_degrees[node2_id]}" |
|
assert ( |
|
node_degrees[node3_id] == 3 |
|
), f"{node3_id} ๅบฆๆฐๅบไธบ3๏ผๅฎ้
ไธบ {node_degrees[node3_id]}" |
|
|
|
|
|
print("== ๆต่ฏ edge_degrees_batch") |
|
edges = [(node1_id, node2_id), (node2_id, node3_id), (node3_id, node4_id)] |
|
edge_degrees = await storage.edge_degrees_batch(edges) |
|
print(f"ๆน้่ทๅ่พนๅบฆๆฐ็ปๆ: {edge_degrees}") |
|
assert ( |
|
len(edge_degrees) == 3 |
|
), f"ๅบ่ฟๅ3ๆก่พน็ๅบฆๆฐ๏ผๅฎ้
่ฟๅ {len(edge_degrees)} ๆก" |
|
assert ( |
|
node1_id, |
|
node2_id, |
|
) in edge_degrees, f"่พน {node1_id} -> {node2_id} ๅบๅจ่ฟๅ็ปๆไธญ" |
|
assert ( |
|
node2_id, |
|
node3_id, |
|
) in edge_degrees, f"่พน {node2_id} -> {node3_id} ๅบๅจ่ฟๅ็ปๆไธญ" |
|
assert ( |
|
node3_id, |
|
node4_id, |
|
) in edge_degrees, f"่พน {node3_id} -> {node4_id} ๅบๅจ่ฟๅ็ปๆไธญ" |
|
|
|
assert ( |
|
edge_degrees[(node1_id, node2_id)] == 5 |
|
), f"่พน {node1_id} -> {node2_id} ๅบฆๆฐๅบไธบ5๏ผๅฎ้
ไธบ {edge_degrees[(node1_id, node2_id)]}" |
|
assert ( |
|
edge_degrees[(node2_id, node3_id)] == 5 |
|
), f"่พน {node2_id} -> {node3_id} ๅบฆๆฐๅบไธบ5๏ผๅฎ้
ไธบ {edge_degrees[(node2_id, node3_id)]}" |
|
assert ( |
|
edge_degrees[(node3_id, node4_id)] == 5 |
|
), f"่พน {node3_id} -> {node4_id} ๅบฆๆฐๅบไธบ5๏ผๅฎ้
ไธบ {edge_degrees[(node3_id, node4_id)]}" |
|
|
|
|
|
print("== ๆต่ฏ get_edges_batch") |
|
|
|
edge_dicts = [{"src": src, "tgt": tgt} for src, tgt in edges] |
|
edges_dict = await storage.get_edges_batch(edge_dicts) |
|
print(f"ๆน้่ทๅ่พนๅฑๆง็ปๆ: {edges_dict.keys()}") |
|
assert len(edges_dict) == 3, f"ๅบ่ฟๅ3ๆก่พน็ๅฑๆง๏ผๅฎ้
่ฟๅ {len(edges_dict)} ๆก" |
|
assert ( |
|
node1_id, |
|
node2_id, |
|
) in edges_dict, f"่พน {node1_id} -> {node2_id} ๅบๅจ่ฟๅ็ปๆไธญ" |
|
assert ( |
|
node2_id, |
|
node3_id, |
|
) in edges_dict, f"่พน {node2_id} -> {node3_id} ๅบๅจ่ฟๅ็ปๆไธญ" |
|
assert ( |
|
node3_id, |
|
node4_id, |
|
) in edges_dict, f"่พน {node3_id} -> {node4_id} ๅบๅจ่ฟๅ็ปๆไธญ" |
|
assert ( |
|
edges_dict[(node1_id, node2_id)]["relationship"] |
|
== edge1_data["relationship"] |
|
), f"่พน {node1_id} -> {node2_id} ๅ
ณ็ณปไธๅน้
" |
|
assert ( |
|
edges_dict[(node2_id, node3_id)]["relationship"] |
|
== edge2_data["relationship"] |
|
), f"่พน {node2_id} -> {node3_id} ๅ
ณ็ณปไธๅน้
" |
|
assert ( |
|
edges_dict[(node3_id, node4_id)]["relationship"] |
|
== edge5_data["relationship"] |
|
), f"่พน {node3_id} -> {node4_id} ๅ
ณ็ณปไธๅน้
" |
|
|
|
|
|
print("== ๆต่ฏๅๅ่พน็ๆน้่ทๅ") |
|
|
|
reverse_edge_dicts = [{"src": tgt, "tgt": src} for src, tgt in edges] |
|
reverse_edges_dict = await storage.get_edges_batch(reverse_edge_dicts) |
|
print(f"ๆน้่ทๅๅๅ่พนๅฑๆง็ปๆ: {reverse_edges_dict.keys()}") |
|
assert ( |
|
len(reverse_edges_dict) == 3 |
|
), f"ๅบ่ฟๅ3ๆกๅๅ่พน็ๅฑๆง๏ผๅฎ้
่ฟๅ {len(reverse_edges_dict)} ๆก" |
|
|
|
|
|
for (src, tgt), props in edges_dict.items(): |
|
assert ( |
|
tgt, |
|
src, |
|
) in reverse_edges_dict, f"ๅๅ่พน {tgt} -> {src} ๅบๅจ่ฟๅ็ปๆไธญ" |
|
assert ( |
|
props == reverse_edges_dict[(tgt, src)] |
|
), f"่พน {src} -> {tgt} ๅๅๅ่พน {tgt} -> {src} ็ๅฑๆงไธไธ่ด" |
|
|
|
print("ๆ ๅๅพ็นๆง้ช่ฏๆๅ๏ผๆน้่ทๅ็ๆญฃๅๅๅๅ่พนๅฑๆงไธ่ด") |
|
|
|
|
|
print("== ๆต่ฏ get_nodes_edges_batch") |
|
nodes_edges = await storage.get_nodes_edges_batch([node1_id, node3_id]) |
|
print(f"ๆน้่ทๅ่็น่พน็ปๆ: {nodes_edges.keys()}") |
|
assert ( |
|
len(nodes_edges) == 2 |
|
), f"ๅบ่ฟๅ2ไธช่็น็่พน๏ผๅฎ้
่ฟๅ {len(nodes_edges)} ไธช" |
|
assert node1_id in nodes_edges, f"{node1_id} ๅบๅจ่ฟๅ็ปๆไธญ" |
|
assert node3_id in nodes_edges, f"{node3_id} ๅบๅจ่ฟๅ็ปๆไธญ" |
|
assert ( |
|
len(nodes_edges[node1_id]) == 3 |
|
), f"{node1_id} ๅบๆ3ๆก่พน๏ผๅฎ้
ๆ {len(nodes_edges[node1_id])} ๆก" |
|
assert ( |
|
len(nodes_edges[node3_id]) == 3 |
|
), f"{node3_id} ๅบๆ3ๆก่พน๏ผๅฎ้
ๆ {len(nodes_edges[node3_id])} ๆก" |
|
|
|
|
|
print("== ้ช่ฏๆน้่ทๅ่็น่พน็ๆ ๅๅพ็นๆง") |
|
|
|
|
|
node1_outgoing_edges = [ |
|
(src, tgt) for src, tgt in nodes_edges[node1_id] if src == node1_id |
|
] |
|
node1_incoming_edges = [ |
|
(src, tgt) for src, tgt in nodes_edges[node1_id] if tgt == node1_id |
|
] |
|
print(f"่็น {node1_id} ็ๅบ่พน: {node1_outgoing_edges}") |
|
print(f"่็น {node1_id} ็ๅ
ฅ่พน: {node1_incoming_edges}") |
|
|
|
|
|
has_edge_to_node2 = any(tgt == node2_id for _, tgt in node1_outgoing_edges) |
|
has_edge_to_node4 = any(tgt == node4_id for _, tgt in node1_outgoing_edges) |
|
has_edge_to_node5 = any(tgt == node5_id for _, tgt in node1_outgoing_edges) |
|
|
|
assert has_edge_to_node2, f"่็น {node1_id} ็่พนๅ่กจไธญๅบๅ
ๅซๅฐ {node2_id} ็่พน" |
|
assert has_edge_to_node4, f"่็น {node1_id} ็่พนๅ่กจไธญๅบๅ
ๅซๅฐ {node4_id} ็่พน" |
|
assert has_edge_to_node5, f"่็น {node1_id} ็่พนๅ่กจไธญๅบๅ
ๅซๅฐ {node5_id} ็่พน" |
|
|
|
|
|
node3_outgoing_edges = [ |
|
(src, tgt) for src, tgt in nodes_edges[node3_id] if src == node3_id |
|
] |
|
node3_incoming_edges = [ |
|
(src, tgt) for src, tgt in nodes_edges[node3_id] if tgt == node3_id |
|
] |
|
print(f"่็น {node3_id} ็ๅบ่พน: {node3_outgoing_edges}") |
|
print(f"่็น {node3_id} ็ๅ
ฅ่พน: {node3_incoming_edges}") |
|
|
|
|
|
has_connection_with_node2 = any( |
|
(src == node2_id and tgt == node3_id) |
|
or (src == node3_id and tgt == node2_id) |
|
for src, tgt in nodes_edges[node3_id] |
|
) |
|
has_connection_with_node4 = any( |
|
(src == node3_id and tgt == node4_id) |
|
or (src == node4_id and tgt == node3_id) |
|
for src, tgt in nodes_edges[node3_id] |
|
) |
|
has_connection_with_node5 = any( |
|
(src == node3_id and tgt == node5_id) |
|
or (src == node5_id and tgt == node3_id) |
|
for src, tgt in nodes_edges[node3_id] |
|
) |
|
|
|
assert ( |
|
has_connection_with_node2 |
|
), f"่็น {node3_id} ็่พนๅ่กจไธญๅบๅ
ๅซไธ {node2_id} ็่ฟๆฅ" |
|
assert ( |
|
has_connection_with_node4 |
|
), f"่็น {node3_id} ็่พนๅ่กจไธญๅบๅ
ๅซไธ {node4_id} ็่ฟๆฅ" |
|
assert ( |
|
has_connection_with_node5 |
|
), f"่็น {node3_id} ็่พนๅ่กจไธญๅบๅ
ๅซไธ {node5_id} ็่ฟๆฅ" |
|
|
|
print("ๆ ๅๅพ็นๆง้ช่ฏๆๅ๏ผๆน้่ทๅ็่็น่พนๅ
ๅซๆๆ็ธๅ
ณ็่พน๏ผๆ ่ฎบๆนๅ๏ผ") |
|
|
|
|
|
print("== ๆต่ฏ get_nodes_by_chunk_ids") |
|
|
|
print("== ๆต่ฏๅไธช chunk_id๏ผๅน้
ๅคไธช่็น") |
|
nodes = await storage.get_nodes_by_chunk_ids([chunk2_id]) |
|
assert len(nodes) == 2, f"{chunk1_id} ๅบๆ2ไธช่็น๏ผๅฎ้
ๆ {len(nodes)} ไธช" |
|
|
|
has_node1 = any(node["entity_id"] == node1_id for node in nodes) |
|
has_node2 = any(node["entity_id"] == node2_id for node in nodes) |
|
|
|
assert has_node1, f"่็น {node1_id} ๅบๅจ่ฟๅ็ปๆไธญ" |
|
assert has_node2, f"่็น {node2_id} ๅบๅจ่ฟๅ็ปๆไธญ" |
|
|
|
print("== ๆต่ฏๅคไธช chunk_id๏ผ้จๅๅน้
ๅคไธช่็น") |
|
nodes = await storage.get_nodes_by_chunk_ids([chunk2_id, chunk3_id]) |
|
assert ( |
|
len(nodes) == 3 |
|
), f"{chunk2_id}, {chunk3_id} ๅบๆ3ไธช่็น๏ผๅฎ้
ๆ {len(nodes)} ไธช" |
|
|
|
has_node1 = any(node["entity_id"] == node1_id for node in nodes) |
|
has_node2 = any(node["entity_id"] == node2_id for node in nodes) |
|
has_node3 = any(node["entity_id"] == node3_id for node in nodes) |
|
|
|
assert has_node1, f"่็น {node1_id} ๅบๅจ่ฟๅ็ปๆไธญ" |
|
assert has_node2, f"่็น {node2_id} ๅบๅจ่ฟๅ็ปๆไธญ" |
|
assert has_node3, f"่็น {node3_id} ๅบๅจ่ฟๅ็ปๆไธญ" |
|
|
|
|
|
print("== ๆต่ฏ get_edges_by_chunk_ids") |
|
|
|
print("== ๆต่ฏๅไธช chunk_id๏ผๅน้
ๅคๆก่พน") |
|
edges = await storage.get_edges_by_chunk_ids([chunk2_id]) |
|
assert len(edges) == 2, f"{chunk2_id} ๅบๆ2ๆก่พน๏ผๅฎ้
ๆ {len(edges)} ๆก" |
|
|
|
has_edge_node1_node2 = any( |
|
edge["source"] == node1_id and edge["target"] == node2_id for edge in edges |
|
) |
|
has_edge_node2_node3 = any( |
|
edge["source"] == node2_id and edge["target"] == node3_id for edge in edges |
|
) |
|
|
|
assert has_edge_node1_node2, f"{chunk2_id} ๅบๅ
ๅซ {node1_id} ๅฐ {node2_id} ็่พน" |
|
assert has_edge_node2_node3, f"{chunk2_id} ๅบๅ
ๅซ {node2_id} ๅฐ {node3_id} ็่พน" |
|
|
|
print("== ๆต่ฏๅคไธช chunk_id๏ผ้จๅๅน้
ๅคๆก่พน") |
|
edges = await storage.get_edges_by_chunk_ids([chunk2_id, chunk3_id]) |
|
assert ( |
|
len(edges) == 3 |
|
), f"{chunk2_id}, {chunk3_id} ๅบๆ3ๆก่พน๏ผๅฎ้
ๆ {len(edges)} ๆก" |
|
|
|
has_edge_node1_node2 = any( |
|
edge["source"] == node1_id and edge["target"] == node2_id for edge in edges |
|
) |
|
has_edge_node2_node3 = any( |
|
edge["source"] == node2_id and edge["target"] == node3_id for edge in edges |
|
) |
|
has_edge_node1_node4 = any( |
|
edge["source"] == node1_id and edge["target"] == node4_id for edge in edges |
|
) |
|
|
|
assert ( |
|
has_edge_node1_node2 |
|
), f"{chunk2_id}, {chunk3_id} ๅบๅ
ๅซ {node1_id} ๅฐ {node2_id} ็่พน" |
|
assert ( |
|
has_edge_node2_node3 |
|
), f"{chunk2_id}, {chunk3_id} ๅบๅ
ๅซ {node2_id} ๅฐ {node3_id} ็่พน" |
|
assert ( |
|
has_edge_node1_node4 |
|
), f"{chunk2_id}, {chunk3_id} ๅบๅ
ๅซ {node1_id} ๅฐ {node4_id} ็่พน" |
|
|
|
print("\nๆน้ๆไฝๆต่ฏๅฎๆ") |
|
return True |
|
|
|
except Exception as e: |
|
ASCIIColors.red(f"ๆต่ฏ่ฟ็จไธญๅ็้่ฏฏ: {str(e)}") |
|
return False |
|
|
|
|
|
async def test_graph_special_characters(storage): |
|
""" |
|
ๆต่ฏๅพๆฐๆฎๅบๅฏน็นๆฎๅญ็ฌฆ็ๅค็: |
|
1. ๆต่ฏ่็นๅ็งฐๅๆ่ฟฐไธญๅ
ๅซๅๅผๅทใๅๅผๅทๅๅๆๆ |
|
2. ๆต่ฏ่พน็ๆ่ฟฐไธญๅ
ๅซๅๅผๅทใๅๅผๅทๅๅๆๆ |
|
3. ้ช่ฏ็นๆฎๅญ็ฌฆๆฏๅฆ่ขซๆญฃ็กฎไฟๅญๅๆฃ็ดข |
|
""" |
|
try: |
|
|
|
node1_id = "ๅ
ๅซ'ๅๅผๅท'็่็น" |
|
node1_data = { |
|
"entity_id": node1_id, |
|
"description": "่ฟไธชๆ่ฟฐๅ
ๅซ'ๅๅผๅท'ใ\"ๅๅผๅท\"ๅ\\ๅๆๆ ", |
|
"keywords": "็นๆฎๅญ็ฌฆ,ๅผๅท,่ฝฌไน", |
|
"entity_type": "ๆต่ฏ่็น", |
|
} |
|
print(f"ๆๅ
ฅๅ
ๅซ็นๆฎๅญ็ฌฆ็่็น1: {node1_id}") |
|
await storage.upsert_node(node1_id, node1_data) |
|
|
|
|
|
node2_id = 'ๅ
ๅซ"ๅๅผๅท"็่็น' |
|
node2_data = { |
|
"entity_id": node2_id, |
|
"description": "่ฟไธชๆ่ฟฐๅๆถๅ
ๅซ'ๅๅผๅท'ๅ\"ๅๅผๅท\"ไปฅๅ\\ๅๆๆ \\่ทฏๅพ", |
|
"keywords": "็นๆฎๅญ็ฌฆ,ๅผๅท,JSON", |
|
"entity_type": "ๆต่ฏ่็น", |
|
} |
|
print(f"ๆๅ
ฅๅ
ๅซ็นๆฎๅญ็ฌฆ็่็น2: {node2_id}") |
|
await storage.upsert_node(node2_id, node2_data) |
|
|
|
|
|
node3_id = "ๅ
ๅซ\\ๅๆๆ \\็่็น" |
|
node3_data = { |
|
"entity_id": node3_id, |
|
"description": "่ฟไธชๆ่ฟฐๅ
ๅซWindows่ทฏๅพC:\\Program Files\\ๅ่ฝฌไนๅญ็ฌฆ\\n\\t", |
|
"keywords": "ๅๆๆ ,่ทฏๅพ,่ฝฌไน", |
|
"entity_type": "ๆต่ฏ่็น", |
|
} |
|
print(f"ๆๅ
ฅๅ
ๅซ็นๆฎๅญ็ฌฆ็่็น3: {node3_id}") |
|
await storage.upsert_node(node3_id, node3_data) |
|
|
|
|
|
edge1_data = { |
|
"relationship": "็นๆฎ'ๅ
ณ็ณป'", |
|
"weight": 1.0, |
|
"description": "่ฟไธช่พนๆ่ฟฐๅ
ๅซ'ๅๅผๅท'ใ\"ๅๅผๅท\"ๅ\\ๅๆๆ ", |
|
} |
|
print(f"ๆๅ
ฅๅ
ๅซ็นๆฎๅญ็ฌฆ็่พน: {node1_id} -> {node2_id}") |
|
await storage.upsert_edge(node1_id, node2_id, edge1_data) |
|
|
|
|
|
edge2_data = { |
|
"relationship": 'ๅคๆ"ๅ
ณ็ณป"\\็ฑปๅ', |
|
"weight": 0.8, |
|
"description": "ๅ
ๅซSQLๆณจๅ
ฅๅฐ่ฏ: SELECT * FROM users WHERE name='admin'--", |
|
} |
|
print(f"ๆๅ
ฅๅ
ๅซๅคๆ็นๆฎๅญ็ฌฆ็่พน: {node2_id} -> {node3_id}") |
|
await storage.upsert_edge(node2_id, node3_id, edge2_data) |
|
|
|
|
|
print("\n== ้ช่ฏ่็น็นๆฎๅญ็ฌฆ") |
|
for node_id, original_data in [ |
|
(node1_id, node1_data), |
|
(node2_id, node2_data), |
|
(node3_id, node3_data), |
|
]: |
|
node_props = await storage.get_node(node_id) |
|
if node_props: |
|
print(f"ๆๅ่ฏปๅ่็น: {node_id}") |
|
print(f"่็นๆ่ฟฐ: {node_props.get('description', 'ๆ ๆ่ฟฐ')}") |
|
|
|
|
|
assert ( |
|
node_props.get("entity_id") == node_id |
|
), f"่็นIDไธๅน้
: ๆๆ {node_id}, ๅฎ้
{node_props.get('entity_id')}" |
|
|
|
|
|
assert ( |
|
node_props.get("description") == original_data["description"] |
|
), f"่็นๆ่ฟฐไธๅน้
: ๆๆ {original_data['description']}, ๅฎ้
{node_props.get('description')}" |
|
|
|
print(f"่็น {node_id} ็นๆฎๅญ็ฌฆ้ช่ฏๆๅ") |
|
else: |
|
print(f"่ฏปๅ่็นๅฑๆงๅคฑ่ดฅ: {node_id}") |
|
assert False, f"ๆช่ฝ่ฏปๅ่็นๅฑๆง: {node_id}" |
|
|
|
|
|
print("\n== ้ช่ฏ่พน็นๆฎๅญ็ฌฆ") |
|
edge1_props = await storage.get_edge(node1_id, node2_id) |
|
if edge1_props: |
|
print(f"ๆๅ่ฏปๅ่พน: {node1_id} -> {node2_id}") |
|
print(f"่พนๅ
ณ็ณป: {edge1_props.get('relationship', 'ๆ ๅ
ณ็ณป')}") |
|
print(f"่พนๆ่ฟฐ: {edge1_props.get('description', 'ๆ ๆ่ฟฐ')}") |
|
|
|
|
|
assert ( |
|
edge1_props.get("relationship") == edge1_data["relationship"] |
|
), f"่พนๅ
ณ็ณปไธๅน้
: ๆๆ {edge1_data['relationship']}, ๅฎ้
{edge1_props.get('relationship')}" |
|
|
|
|
|
assert ( |
|
edge1_props.get("description") == edge1_data["description"] |
|
), f"่พนๆ่ฟฐไธๅน้
: ๆๆ {edge1_data['description']}, ๅฎ้
{edge1_props.get('description')}" |
|
|
|
print(f"่พน {node1_id} -> {node2_id} ็นๆฎๅญ็ฌฆ้ช่ฏๆๅ") |
|
else: |
|
print(f"่ฏปๅ่พนๅฑๆงๅคฑ่ดฅ: {node1_id} -> {node2_id}") |
|
assert False, f"ๆช่ฝ่ฏปๅ่พนๅฑๆง: {node1_id} -> {node2_id}" |
|
|
|
edge2_props = await storage.get_edge(node2_id, node3_id) |
|
if edge2_props: |
|
print(f"ๆๅ่ฏปๅ่พน: {node2_id} -> {node3_id}") |
|
print(f"่พนๅ
ณ็ณป: {edge2_props.get('relationship', 'ๆ ๅ
ณ็ณป')}") |
|
print(f"่พนๆ่ฟฐ: {edge2_props.get('description', 'ๆ ๆ่ฟฐ')}") |
|
|
|
|
|
assert ( |
|
edge2_props.get("relationship") == edge2_data["relationship"] |
|
), f"่พนๅ
ณ็ณปไธๅน้
: ๆๆ {edge2_data['relationship']}, ๅฎ้
{edge2_props.get('relationship')}" |
|
|
|
|
|
assert ( |
|
edge2_props.get("description") == edge2_data["description"] |
|
), f"่พนๆ่ฟฐไธๅน้
: ๆๆ {edge2_data['description']}, ๅฎ้
{edge2_props.get('description')}" |
|
|
|
print(f"่พน {node2_id} -> {node3_id} ็นๆฎๅญ็ฌฆ้ช่ฏๆๅ") |
|
else: |
|
print(f"่ฏปๅ่พนๅฑๆงๅคฑ่ดฅ: {node2_id} -> {node3_id}") |
|
assert False, f"ๆช่ฝ่ฏปๅ่พนๅฑๆง: {node2_id} -> {node3_id}" |
|
|
|
print("\n็นๆฎๅญ็ฌฆๆต่ฏๅฎๆ๏ผๆฐๆฎๅทฒไฟ็ๅจๆฐๆฎๅบไธญ") |
|
return True |
|
|
|
except Exception as e: |
|
ASCIIColors.red(f"ๆต่ฏ่ฟ็จไธญๅ็้่ฏฏ: {str(e)}") |
|
return False |
|
|
|
|
|
async def test_graph_undirected_property(storage): |
|
""" |
|
ไธ้จๆต่ฏๅพๅญๅจ็ๆ ๅๅพ็นๆง: |
|
1. ้ช่ฏๆๅ
ฅไธไธชๆนๅ็่พนๅ๏ผๅๅๆฅ่ฏขๆฏๅฆ่ฝ่ทๅพ็ธๅ็็ปๆ |
|
2. ้ช่ฏ่พน็ๅฑๆงๅจๆญฃๅๅๅๅๆฅ่ฏขไธญๆฏๅฆไธ่ด |
|
3. ้ช่ฏๅ ้คไธไธชๆนๅ็่พนๅ๏ผๅฆไธไธชๆนๅ็่พนๆฏๅฆไน่ขซๅ ้ค |
|
4. ้ช่ฏๆน้ๆไฝไธญ็ๆ ๅๅพ็นๆง |
|
""" |
|
try: |
|
|
|
|
|
node1_id = "่ฎก็ฎๆบ็งๅญฆ" |
|
node1_data = { |
|
"entity_id": node1_id, |
|
"description": "่ฎก็ฎๆบ็งๅญฆๆฏ็ ็ฉถ่ฎก็ฎๆบๅๅ
ถๅบ็จ็็งๅญฆใ", |
|
"keywords": "่ฎก็ฎๆบ,็งๅญฆ,ๆๆฏ", |
|
"entity_type": "ๅญฆ็ง", |
|
} |
|
print(f"ๆๅ
ฅ่็น1: {node1_id}") |
|
await storage.upsert_node(node1_id, node1_data) |
|
|
|
|
|
node2_id = "ๆฐๆฎ็ปๆ" |
|
node2_data = { |
|
"entity_id": node2_id, |
|
"description": "ๆฐๆฎ็ปๆๆฏ่ฎก็ฎๆบ็งๅญฆไธญ็ไธไธชๅบ็กๆฆๅฟต๏ผ็จไบ็ป็ปๅๅญๅจๆฐๆฎใ", |
|
"keywords": "ๆฐๆฎ,็ปๆ,็ป็ป", |
|
"entity_type": "ๆฆๅฟต", |
|
} |
|
print(f"ๆๅ
ฅ่็น2: {node2_id}") |
|
await storage.upsert_node(node2_id, node2_data) |
|
|
|
|
|
node3_id = "็ฎๆณ" |
|
node3_data = { |
|
"entity_id": node3_id, |
|
"description": "็ฎๆณๆฏ่งฃๅณ้ฎ้ข็ๆญฅ้ชคๅๆนๆณใ", |
|
"keywords": "็ฎๆณ,ๆญฅ้ชค,ๆนๆณ", |
|
"entity_type": "ๆฆๅฟต", |
|
} |
|
print(f"ๆๅ
ฅ่็น3: {node3_id}") |
|
await storage.upsert_node(node3_id, node3_data) |
|
|
|
|
|
print("\n== ๆต่ฏๆๅ
ฅ่พนๅ็ๆ ๅๅพ็นๆง") |
|
|
|
|
|
edge1_data = { |
|
"relationship": "ๅ
ๅซ", |
|
"weight": 1.0, |
|
"description": "่ฎก็ฎๆบ็งๅญฆๅ
ๅซๆฐๆฎ็ปๆ่ฟไธชๆฆๅฟต", |
|
} |
|
print(f"ๆๅ
ฅ่พน1: {node1_id} -> {node2_id}") |
|
await storage.upsert_edge(node1_id, node2_id, edge1_data) |
|
|
|
|
|
forward_edge = await storage.get_edge(node1_id, node2_id) |
|
print(f"ๆญฃๅ่พนๅฑๆง: {forward_edge}") |
|
assert forward_edge is not None, f"ๆช่ฝ่ฏปๅๆญฃๅ่พนๅฑๆง: {node1_id} -> {node2_id}" |
|
|
|
|
|
reverse_edge = await storage.get_edge(node2_id, node1_id) |
|
print(f"ๅๅ่พนๅฑๆง: {reverse_edge}") |
|
assert reverse_edge is not None, f"ๆช่ฝ่ฏปๅๅๅ่พนๅฑๆง: {node2_id} -> {node1_id}" |
|
|
|
|
|
assert ( |
|
forward_edge == reverse_edge |
|
), "ๆญฃๅๅๅๅ่พนๅฑๆงไธไธ่ด๏ผๆ ๅๅพ็นๆง้ช่ฏๅคฑ่ดฅ" |
|
print("ๆ ๅๅพ็นๆง้ช่ฏๆๅ๏ผๆญฃๅๅๅๅ่พนๅฑๆงไธ่ด") |
|
|
|
|
|
print("\n== ๆต่ฏ่พน็ๅบฆๆฐ็ๆ ๅๅพ็นๆง") |
|
|
|
|
|
edge2_data = { |
|
"relationship": "ๅ
ๅซ", |
|
"weight": 1.0, |
|
"description": "่ฎก็ฎๆบ็งๅญฆๅ
ๅซ็ฎๆณ่ฟไธชๆฆๅฟต", |
|
} |
|
print(f"ๆๅ
ฅ่พน2: {node1_id} -> {node3_id}") |
|
await storage.upsert_edge(node1_id, node3_id, edge2_data) |
|
|
|
|
|
forward_degree = await storage.edge_degree(node1_id, node2_id) |
|
reverse_degree = await storage.edge_degree(node2_id, node1_id) |
|
print(f"ๆญฃๅ่พน {node1_id} -> {node2_id} ็ๅบฆๆฐ: {forward_degree}") |
|
print(f"ๅๅ่พน {node2_id} -> {node1_id} ็ๅบฆๆฐ: {reverse_degree}") |
|
assert ( |
|
forward_degree == reverse_degree |
|
), "ๆญฃๅๅๅๅ่พน็ๅบฆๆฐไธไธ่ด๏ผๆ ๅๅพ็นๆง้ช่ฏๅคฑ่ดฅ" |
|
print("ๆ ๅๅพ็นๆง้ช่ฏๆๅ๏ผๆญฃๅๅๅๅ่พน็ๅบฆๆฐไธ่ด") |
|
|
|
|
|
print("\n== ๆต่ฏๅ ้ค่พน็ๆ ๅๅพ็นๆง") |
|
|
|
|
|
print(f"ๅ ้ค่พน: {node1_id} -> {node2_id}") |
|
await storage.remove_edges([(node1_id, node2_id)]) |
|
|
|
|
|
forward_edge = await storage.get_edge(node1_id, node2_id) |
|
print(f"ๅ ้คๅๆฅ่ฏขๆญฃๅ่พนๅฑๆง {node1_id} -> {node2_id}: {forward_edge}") |
|
assert forward_edge is None, f"่พน {node1_id} -> {node2_id} ๅบๅทฒ่ขซๅ ้ค" |
|
|
|
|
|
reverse_edge = await storage.get_edge(node2_id, node1_id) |
|
print(f"ๅ ้คๅๆฅ่ฏขๅๅ่พนๅฑๆง {node2_id} -> {node1_id}: {reverse_edge}") |
|
assert ( |
|
reverse_edge is None |
|
), f"ๅๅ่พน {node2_id} -> {node1_id} ไนๅบ่ขซๅ ้ค๏ผๆ ๅๅพ็นๆง้ช่ฏๅคฑ่ดฅ" |
|
print("ๆ ๅๅพ็นๆง้ช่ฏๆๅ๏ผๅ ้คไธไธชๆนๅ็่พนๅ๏ผๅๅ่พนไน่ขซๅ ้ค") |
|
|
|
|
|
print("\n== ๆต่ฏๆน้ๆไฝไธญ็ๆ ๅๅพ็นๆง") |
|
|
|
|
|
await storage.upsert_edge(node1_id, node2_id, edge1_data) |
|
|
|
|
|
edge_dicts = [ |
|
{"src": node1_id, "tgt": node2_id}, |
|
{"src": node1_id, "tgt": node3_id}, |
|
] |
|
reverse_edge_dicts = [ |
|
{"src": node2_id, "tgt": node1_id}, |
|
{"src": node3_id, "tgt": node1_id}, |
|
] |
|
|
|
edges_dict = await storage.get_edges_batch(edge_dicts) |
|
reverse_edges_dict = await storage.get_edges_batch(reverse_edge_dicts) |
|
|
|
print(f"ๆน้่ทๅๆญฃๅ่พนๅฑๆง็ปๆ: {edges_dict.keys()}") |
|
print(f"ๆน้่ทๅๅๅ่พนๅฑๆง็ปๆ: {reverse_edges_dict.keys()}") |
|
|
|
|
|
for (src, tgt), props in edges_dict.items(): |
|
assert ( |
|
tgt, |
|
src, |
|
) in reverse_edges_dict, f"ๅๅ่พน {tgt} -> {src} ๅบๅจ่ฟๅ็ปๆไธญ" |
|
assert ( |
|
props == reverse_edges_dict[(tgt, src)] |
|
), f"่พน {src} -> {tgt} ๅๅๅ่พน {tgt} -> {src} ็ๅฑๆงไธไธ่ด" |
|
|
|
print("ๆ ๅๅพ็นๆง้ช่ฏๆๅ๏ผๆน้่ทๅ็ๆญฃๅๅๅๅ่พนๅฑๆงไธ่ด") |
|
|
|
|
|
print("\n== ๆต่ฏๆน้่ทๅ่็น่พน็ๆ ๅๅพ็นๆง") |
|
|
|
nodes_edges = await storage.get_nodes_edges_batch([node1_id, node2_id]) |
|
print(f"ๆน้่ทๅ่็น่พน็ปๆ: {nodes_edges.keys()}") |
|
|
|
|
|
node1_edges = nodes_edges[node1_id] |
|
node2_edges = nodes_edges[node2_id] |
|
|
|
|
|
has_edge_to_node2 = any( |
|
(src == node1_id and tgt == node2_id) for src, tgt in node1_edges |
|
) |
|
has_edge_to_node3 = any( |
|
(src == node1_id and tgt == node3_id) for src, tgt in node1_edges |
|
) |
|
|
|
assert has_edge_to_node2, f"่็น {node1_id} ็่พนๅ่กจไธญๅบๅ
ๅซๅฐ {node2_id} ็่พน" |
|
assert has_edge_to_node3, f"่็น {node1_id} ็่พนๅ่กจไธญๅบๅ
ๅซๅฐ {node3_id} ็่พน" |
|
|
|
|
|
has_edge_to_node1 = any( |
|
(src == node2_id and tgt == node1_id) |
|
or (src == node1_id and tgt == node2_id) |
|
for src, tgt in node2_edges |
|
) |
|
assert ( |
|
has_edge_to_node1 |
|
), f"่็น {node2_id} ็่พนๅ่กจไธญๅบๅ
ๅซไธ {node1_id} ็่ฟๆฅ" |
|
|
|
print("ๆ ๅๅพ็นๆง้ช่ฏๆๅ๏ผๆน้่ทๅ็่็น่พนๅ
ๅซๆๆ็ธๅ
ณ็่พน๏ผๆ ่ฎบๆนๅ๏ผ") |
|
|
|
print("\nๆ ๅๅพ็นๆงๆต่ฏๅฎๆ") |
|
return True |
|
|
|
except Exception as e: |
|
ASCIIColors.red(f"ๆต่ฏ่ฟ็จไธญๅ็้่ฏฏ: {str(e)}") |
|
return False |
|
|
|
|
|
async def main(): |
|
"""ไธปๅฝๆฐ""" |
|
|
|
ASCIIColors.cyan(""" |
|
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ |
|
โ ้็จๅพๅญๅจๆต่ฏ็จๅบ โ |
|
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ |
|
""") |
|
|
|
|
|
if not check_env_file(): |
|
return |
|
|
|
|
|
load_dotenv(dotenv_path=".env", override=False) |
|
|
|
|
|
graph_storage_type = os.getenv("LIGHTRAG_GRAPH_STORAGE", "NetworkXStorage") |
|
ASCIIColors.magenta(f"\nๅฝๅ้
็ฝฎ็ๅพๅญๅจ็ฑปๅ: {graph_storage_type}") |
|
ASCIIColors.white( |
|
f"ๆฏๆ็ๅพๅญๅจ็ฑปๅ: {', '.join(STORAGE_IMPLEMENTATIONS['GRAPH_STORAGE']['implementations'])}" |
|
) |
|
|
|
|
|
storage = await initialize_graph_storage() |
|
if not storage: |
|
ASCIIColors.red("ๅๅงๅๅญๅจๅฎไพๅคฑ่ดฅ๏ผๆต่ฏ็จๅบ้ๅบ") |
|
return |
|
|
|
try: |
|
|
|
ASCIIColors.yellow("\n่ฏท้ๆฉๆต่ฏ็ฑปๅ:") |
|
ASCIIColors.white("1. ๅบๆฌๆต่ฏ (่็นๅ่พน็ๆๅ
ฅใ่ฏปๅ)") |
|
ASCIIColors.white("2. ้ซ็บงๆต่ฏ (ๅบฆๆฐใๆ ็ญพใ็ฅ่ฏๅพ่ฐฑใๅ ้คๆไฝ็ญ)") |
|
ASCIIColors.white("3. ๆน้ๆไฝๆต่ฏ (ๆน้่ทๅ่็นใ่พนๅฑๆงๅๅบฆๆฐ็ญ)") |
|
ASCIIColors.white("4. ๆ ๅๅพ็นๆงๆต่ฏ (้ช่ฏๅญๅจ็ๆ ๅๅพ็นๆง)") |
|
ASCIIColors.white("5. ็นๆฎๅญ็ฌฆๆต่ฏ (้ช่ฏๅๅผๅทใๅๅผๅทๅๅๆๆ ็ญ็นๆฎๅญ็ฌฆ)") |
|
ASCIIColors.white("6. ๅ
จ้จๆต่ฏ") |
|
|
|
choice = input("\n่ฏท่พๅ
ฅ้้กน (1/2/3/4/5/6): ") |
|
|
|
|
|
if choice in ["1", "2", "3", "4", "5", "6"]: |
|
ASCIIColors.yellow("\nๆง่กๆต่ฏๅๆธ
็ๆฐๆฎ...") |
|
await storage.drop() |
|
ASCIIColors.green("ๆฐๆฎๆธ
็ๅฎๆ\n") |
|
|
|
if choice == "1": |
|
await test_graph_basic(storage) |
|
elif choice == "2": |
|
await test_graph_advanced(storage) |
|
elif choice == "3": |
|
await test_graph_batch_operations(storage) |
|
elif choice == "4": |
|
await test_graph_undirected_property(storage) |
|
elif choice == "5": |
|
await test_graph_special_characters(storage) |
|
elif choice == "6": |
|
ASCIIColors.cyan("\n=== ๅผๅงๅบๆฌๆต่ฏ ===") |
|
basic_result = await test_graph_basic(storage) |
|
|
|
if basic_result: |
|
ASCIIColors.cyan("\n=== ๅผๅง้ซ็บงๆต่ฏ ===") |
|
advanced_result = await test_graph_advanced(storage) |
|
|
|
if advanced_result: |
|
ASCIIColors.cyan("\n=== ๅผๅงๆน้ๆไฝๆต่ฏ ===") |
|
batch_result = await test_graph_batch_operations(storage) |
|
|
|
if batch_result: |
|
ASCIIColors.cyan("\n=== ๅผๅงๆ ๅๅพ็นๆงๆต่ฏ ===") |
|
undirected_result = await test_graph_undirected_property( |
|
storage |
|
) |
|
|
|
if undirected_result: |
|
ASCIIColors.cyan("\n=== ๅผๅง็นๆฎๅญ็ฌฆๆต่ฏ ===") |
|
await test_graph_special_characters(storage) |
|
else: |
|
ASCIIColors.red("ๆ ๆ็้้กน") |
|
|
|
finally: |
|
|
|
if storage: |
|
await storage.finalize() |
|
ASCIIColors.green("\nๅญๅจ่ฟๆฅๅทฒๅ
ณ้ญ") |
|
|
|
|
|
if __name__ == "__main__": |
|
asyncio.run(main()) |
|
|