Results API¶
The ResultSet and Result classes provide Python-friendly interfaces for working with query results from ArcadeDB. They handle iteration, property access, and type conversion automatically.
Using Context Managers
For automatic resource cleanup, prefer using context managers:
with arcadedb.open_database("./mydb") as db:
result_set = db.query("sql", "SELECT FROM Person WHERE age > 25")
for result in result_set:
print(result.get("name"))
# Database automatically closed
db.close() for clarity, but context managers are recommended in production.
Overview¶
When you execute a query, ArcadeDB returns a ResultSet that can be iterated to access individual Result objects. Each Result represents one row/record from your query.
Key Features:
- Pythonic iteration: Use
forloops or iterators - Property access: Get values by property name
- Type conversion: Automatic conversion from Java to Python types
- Multiple access patterns: Dict-like access, JSON export, direct properties
ResultSet Class¶
Iterable wrapper for query results. Supports both Python iteration (for) and manual iteration (has_next()/next()).
Creation¶
ResultSet objects are returned by query operations:
import arcadedb_embedded as arcadedb
db = arcadedb.open_database("./mydb")
# query() returns ResultSet
result_set = db.query("sql", "SELECT FROM Person WHERE age > 25")
# command() also returns ResultSet for SELECT queries
result_set = db.command("sql", "SELECT * FROM Person LIMIT 10")
Iteration¶
Python-style iteration (recommended):
# Using for loop (most Pythonic)
for result in result_set:
name = result.get("name")
age = result.get("age")
print(f"{name}: {age}")
# As iterator
result_set = db.query("sql", "SELECT FROM Product")
results = list(result_set) # Convert to list
Manual iteration:
# Check and iterate manually
while result_set.has_next():
result = result_set.next()
print(result.to_dict())
has_next() -> bool¶
Check if there are more results available.
Returns:
bool:Trueif more results exist,Falseotherwise
Example:
result_set = db.query("sql", "SELECT FROM User LIMIT 5")
count = 0
while result_set.has_next():
result = result_set.next()
count += 1
print(f"Found {count} results")
next() -> Result¶
Get the next result.
Returns:
Result: Next result object
Raises:
StopIteration: When no more results available
Example:
result_set = db.query("sql", "SELECT FROM Document")
if result_set.has_next():
first = result_set.next()
print(first.to_dict())
close()¶
Close the result set and release resources.
Example:
result_set = db.query("sql", "SELECT FROM LargeTable")
try:
for result in result_set:
process(result)
finally:
result_set.close() # Ensure cleanup
Note: In most cases, result sets are automatically cleaned up when they go out of scope. Explicit closing is only needed for long-running operations or very large result sets.
Result Class¶
Represents a single result row/record from a query.
Creation¶
Result objects are created automatically when iterating a ResultSet:
result_set = db.query("sql", "SELECT FROM Person")
# Each iteration gives you a Result
for result in result_set:
# result is a Result object
pass
get(name: str) -> Any¶
Get the value of a property by name.
Parameters:
name(str): Property name
Returns:
Any: Property value (type depends on the data), orNoneif property doesn't exist- Automatically converts Java types to Python types
- Java
Boolean→ Pythonbool - Java
Integer/Long→ Pythonint - Java
Float/Double→ Pythonfloat - Java
String→ Pythonstr - Java collections → Python lists/dicts
Example:
result_set = db.query("sql", "SELECT name, age, active FROM User")
for result in result_set:
name = result.get("name") # str
age = result.get("age") # int
active = result.get("active") # bool (converted from Java Boolean)
print(f"{name} is {age} years old, active: {active}")
# Handle optional properties with fallback
email = result.get("email") or "unknown@example.com"
print(f"Email: {email}")
has_property(name: str) -> bool¶
Check if a property exists in the result.
Parameters:
name(str): Property name to check
Returns:
bool:Trueif property exists,Falseotherwise
Example:
result_set = db.query("sql", "SELECT * FROM Person")
for result in result_set:
if result.has_property("email"):
email = result.get("email")
print(f"Email: {email}")
else:
print("No email address")
get_property_names() -> List[str]¶
Get list of all property names in the result.
Returns:
List[str]: List of property names
Example:
result_set = db.query("sql", "SELECT * FROM Document LIMIT 1")
for result in result_set:
properties = result.get_property_names()
print(f"Properties: {', '.join(properties)}")
for prop in properties:
value = result.get(prop)
print(f" {prop}: {value}")
to_dict() -> Dict[str, Any]¶
Convert the result to a Python dictionary.
Returns:
Dict[str, Any]: Dictionary with property names as keys
Example:
result_set = db.query("sql", "SELECT name, age, city FROM Person")
# Convert all results to list of dicts
people = [result.to_dict() for result in result_set]
for person in people:
print(person)
# {'name': 'Alice', 'age': 30, 'city': 'NYC'}
Use Cases:
- Converting to pandas DataFrame
- Serialization to JSON (via
json.dumps()) - Passing data to other libraries
- Debugging/inspection
to_json() -> str¶
Convert the result to a JSON string.
Returns:
str: JSON representation of the result
Example:
result_set = db.query("sql", "SELECT * FROM Product WHERE price > 100")
for result in result_set:
json_str = result.to_json()
print(json_str)
# {"@rid":"#1:0","@type":"Product","name":"Laptop","price":999.99}
Note: The JSON includes ArcadeDB metadata like @rid (record ID) and @type (type name).
Common Patterns¶
Converting to Lists and Dicts¶
# List of dictionaries (most common)
result_set = db.query("sql", "SELECT FROM User")
users = [result.to_dict() for result in result_set]
# List of specific property values
result_set = db.query("sql", "SELECT name FROM User")
names = [result.get("name") for result in result_set]
# Dictionary keyed by ID
result_set = db.query("sql", "SELECT id, name FROM User")
user_map = {
result.get("id"): result.get("name")
for result in result_set
}
Pandas Integration¶
import pandas as pd
import arcadedb_embedded as arcadedb
db = arcadedb.open_database("./mydb")
# Query and convert to DataFrame
result_set = db.query("sql", "SELECT name, age, city FROM Person")
df = pd.DataFrame([result.to_dict() for result in result_set])
print(df.head())
# name age city
# 0 Alice 30 NYC
# 1 Bob 25 LA
# 2 Charlie 35 Boston
Processing Large Result Sets¶
For memory efficiency with large datasets:
# Process in batches
result_set = db.query("sql", "SELECT FROM LargeTable")
batch = []
batch_size = 1000
for result in result_set:
batch.append(result.to_dict())
if len(batch) >= batch_size:
# Process batch
process_batch(batch)
batch = []
# Process remaining
if batch:
process_batch(batch)
Conditional Property Access¶
result_set = db.query("sql", "SELECT * FROM Product")
for result in result_set:
# Safely get optional properties
discount = (
result.get("discount")
if result.has_property("discount")
else 0.0
)
price = result.get("price")
final_price = price * (1 - discount)
print(f"Price: ${final_price:.2f}")
Extracting RIDs and Types¶
result_set = db.query("sql", "SELECT FROM Person")
for result in result_set:
# Get ArcadeDB metadata
rid = result.get("@rid") # Record ID (e.g., "#1:0")
rec_type = result.get("@type") # Type name (e.g., "Person")
# Get user properties
name = result.get("name")
print(f"[{rid}] {rec_type}: {name}")
Converting Results to Vertices for Modification¶
Query results are read-only by default. To modify a vertex or edge returned from a query, convert it to a mutable Vertex or Edge object using .get_vertex() or .get_edge().
get_vertex() -> Optional[Vertex]¶
Convert a Result to a mutable Vertex object (if the result is a vertex).
import arcadedb_embedded as arcadedb
db = arcadedb.open_database("./mydb")
# Query returns read-only Results
result_set = db.query("sql", "SELECT FROM Person WHERE name = 'Alice'")
with db.transaction():
for result in result_set:
# Convert Result to mutable Vertex
vertex = result.get_vertex()
if vertex:
# Now you can modify it
vertex.set("age", 31)
vertex.set("updated", True)
vertex.save()
print(f"Updated: {result.get('name')}")
get_edge() -> Optional[Edge]¶
Convert a Result to a mutable Edge object (if the result is an edge).
# Query edges
result_set = db.query("sql", "SELECT FROM FRIEND_OF")
with db.transaction():
for result in result_set:
# Convert Result to mutable Edge
edge = result.get_edge()
if edge:
edge.set("strength", 0.95)
edge.save()
Full Example: Bulk Update with Caching¶
import arcadedb_embedded as arcadedb
db = arcadedb.open_database("./mydb")
# Query all movies
movies = list(db.query("sql", "SELECT FROM Movie"))
print(f"Processing {len(movies)} movies...")
with db.transaction():
for movie_result in movies:
# Convert to mutable vertex
movie = movie_result.get_vertex()
if not movie:
continue
# Modify the vertex
title = movie_result.get("title")
# Add embedding or update properties
movie.set("processed", True)
movie.set("updated_at", "2024-01-02")
movie.save()
print(f"✓ Updated: {title}")
db.close()
Key Distinction:
| Object | Read | Write |
|---|---|---|
Result (from query) |
✅ Yes | ❌ No |
Vertex/Edge (mutable) |
✅ Yes | ✅ Yes |
Created with db.new_vertex() |
✅ Yes | ✅ Yes |
Looked up with db.lookup_by_rid() |
✅ Yes | ✅ Yes |
Complete Examples¶
User Search and Display¶
import arcadedb_embedded as arcadedb
db = arcadedb.open_database("./users_db")
def search_users(name_pattern):
"""Search users by name pattern."""
query = f"""
SELECT name, email, created_at
FROM User
WHERE name LIKE '%{name_pattern}%'
ORDER BY name
"""
result_set = db.query("sql", query)
users = []
for result in result_set:
user = {
'name': result.get("name"),
'email': result.get("email"),
'created_at': result.get("created_at")
}
users.append(user)
return users
# Search
results = search_users("John")
print(f"Found {len(results)} users:")
for user in results:
print(f" {user['name']} <{user['email']}>")
db.close()
Graph Traversal Results¶
import arcadedb_embedded as arcadedb
db = arcadedb.open_database("./social_graph")
# Find friends of friends
query = """
SELECT
@rid as person_rid,
name,
out('Follows').out('Follows').name as friends_of_friends
FROM Person
WHERE name = 'Alice'
"""
result_set = db.query("sql", query)
for result in result_set:
person_name = result.get("name")
friends_of_friends = result.get("friends_of_friends")
print(f"{person_name}'s extended network:")
# friends_of_friends is a Java collection, convert to Python
if friends_of_friends:
fof_list = list(friends_of_friends)
for friend in fof_list:
print(f" - {friend}")
db.close()
Aggregation Results¶
import arcadedb_embedded as arcadedb
db = arcadedb.open_database("./analytics_db")
# Group by and aggregation
query = """
SELECT
category,
COUNT(*) as product_count,
AVG(price) as avg_price,
MAX(price) as max_price
FROM Product
GROUP BY category
ORDER BY product_count DESC
"""
result_set = db.query("sql", query)
print("Product Statistics by Category:")
print("-" * 60)
for result in result_set:
category = result.get("category")
count = result.get("product_count")
avg_price = result.get("avg_price")
max_price = result.get("max_price")
print(f"{category}:")
print(f" Products: {count}")
print(f" Avg Price: ${avg_price:.2f}")
print(f" Max Price: ${max_price:.2f}")
print()
db.close()
Export to JSON File¶
import arcadedb_embedded as arcadedb
import json
db = arcadedb.open_database("./mydb")
# Export query results to JSON file
result_set = db.query("sql", "SELECT * FROM Document")
# Method 1: Using to_dict()
documents = [result.to_dict() for result in result_set]
with open("export.json", "w") as f:
json.dump(documents, f, indent=2, default=str)
# Method 2: Using to_json() directly
result_set = db.query("sql", "SELECT * FROM Document")
with open("export_raw.jsonl", "w") as f:
for result in result_set:
f.write(result.to_json() + "\n")
db.close()
Cypher Query Results¶
import arcadedb_embedded as arcadedb
db = arcadedb.open_database("./graph_db")
# Cypher queries also return ResultSet
cypher_query = """
MATCH (p:Person)-[:WORKS_AT]->(c:Company)
WHERE c.name = 'TechCorp'
RETURN p.name AS employee, p.role AS position
"""
result_set = db.query("cypher", cypher_query)
print("TechCorp Employees:")
for result in result_set:
employee = result.get("employee")
position = result.get("position")
print(f" {employee} - {position}")
db.close()
Error Handling¶
from arcadedb_embedded import ArcadeDBError
result_set = db.query("sql", "SELECT * FROM Person")
for result in result_set:
try:
# Safe property access
name = result.get("name")
# May not exist
if result.has_property("phone"):
phone = result.get("phone")
else:
phone = "N/A"
print(f"{name}: {phone}")
except ArcadeDBError as e:
print(f"Error accessing properties: {e}")
continue
Type Handling¶
ArcadeDB returns Java types that are automatically converted:
| Java Type | Python Type | Notes |
|---|---|---|
java.lang.String |
str |
Direct conversion |
java.lang.Integer, Long |
int |
Numeric conversion |
java.lang.Float, Double |
float |
Numeric conversion |
java.lang.Boolean |
bool |
Explicitly converted |
java.util.ArrayList |
list |
Iterable conversion |
java.util.HashMap |
dict |
Key-value conversion |
null |
None |
Direct mapping |
Boolean Conversion:
The Result class explicitly converts Java Boolean to Python bool:
# This is handled automatically
result_set = db.query("sql", "SELECT active FROM User")
for result in result_set:
active = result.get("active") # Python bool
if active: # Works as expected
print("User is active")
Performance Tips¶
Minimize Property Access¶
# Less efficient: Multiple property accesses
for result in result_set:
if result.get("age") > 25:
name = result.get("name")
age = result.get("age")
print(f"{name}: {age}")
# More efficient: Access once, reuse
for result in result_set:
age = result.get("age")
if age > 25:
name = result.get("name")
print(f"{name}: {age}")
Use to_dict() for Multiple Properties¶
# When accessing many properties, convert to dict once
for result in result_set:
data = result.to_dict()
# Now access from Python dict (faster)
process(
data["name"],
data["age"],
data["email"],
data["phone"]
)
Stream Processing¶
# Don't collect all results if you can process incrementally
result_set = db.query("sql", "SELECT * FROM LargeTable")
# Process as you iterate (memory efficient)
total = 0
for result in result_set:
value = result.get("amount")
total += value
# Better than:
# results = list(result_set) # Loads everything into memory
See Also¶
- Database API - Query and command methods
- Query Guide - Writing effective queries
- Transaction API - Transaction context
- Graph Operations Guide - Working with graph results