Query Builder¶
The ComposeQuery class provides schema-aware query operations.
Getting a Query Builder¶
# From client with schema
q = hb.query("facts", schema=schema)
# From collection (schema loaded from server)
q = hb.collection("facts").query()
Universal Methods¶
Available on all molecule types.
search()¶
Semantic similarity search.
results = q.search("machine learning", top_k=10)
# Slot-specific search (chain molecules only)
results = q.search("Einstein", slot="subject")
search_slots()¶
Multi-slot weighted search.
results = q.search_slots({
"subject": ("Einstein", 2.0), # Query, weight
"object": ("physics", 1.0),
})
search_prototype()¶
Find items similar to any of the examples.
all()¶
Fetch all rows.
Slot-Based Methods¶
For chain-encoded molecules (Pair, Triple, Tree, Graph).
find()¶
Find by field values.
# Find all facts about Einstein
results = q.find(subject="Einstein")
# Find all "works_at" relationships
results = q.find(predicate="works_at")
# Combined
results = q.find(subject="Einstein", predicate="works_at")
Nested schema support: For nested schemas, use column names directly:
# Schema: Triple(subject=Pair(left=Field("universe"), right=Field("name")), ...)
schema = Triple(
subject=Pair(
left=Field("subject_universe", encoding=Encoding.EXACT),
right=Field("subject_name", encoding=Encoding.SEMANTIC),
),
predicate=Field("relation", encoding=Encoding.EXACT),
object=Field("target"),
)
q = hb.query("characters", schema=schema)
# Query by column name (recommended)
results = q.find(subject_universe="Marvel", subject_name="Thor")
# Query by top-level slot (backward compatible)
results = q.find(subject="Thor")
# Query by dot notation (explicit path)
results = q.find(**{"subject.left": "Marvel"})
get()¶
Exact single-row lookup.
result = q.get(subject="Einstein", predicate="born_in")
# Returns single result or raises NotFoundError
Traversal Methods¶
For Triple, Tree, and Graph molecules.
traverse()¶
Multi-hop path following.
# Exact traversal
results = q.traverse(
start={"subject": "Einstein"},
path=["worked_at", "located_in"],
)
traverse_fuzzy()¶
Semantic path following.
results = q.traverse_fuzzy(
start="Albert Einstein",
start_slot="subject",
path=["employment", "location"],
hop_threshold=0.6, # Minimum similarity per hop
)
Tree-Specific Methods¶
For Tree and Hierarchy molecules.
children()¶
Get direct children of a node.
parent()¶
Get parent of a node.
ancestors()¶
Get all ancestors up the tree.
descendants()¶
Get all descendants down the tree.
siblings()¶
Get nodes with same parent.
Graph-Specific Methods¶
For Graph and Network molecules.
neighbors()¶
Get connected nodes.
path()¶
Find path between nodes.
subgraph()¶
Extract local neighborhood.
Filter & Select Methods¶
SQL-like operations.
filter()¶
Apply conditions.
select()¶
Column projection.
aggregate()¶
GROUP BY aggregation.
Method Chaining¶
Methods can be chained:
Result Types¶
hybi.compose.ComposeResult
dataclass
¶
A single result from a Compose query.
ComposeResult wraps search results with schema-aware slot accessors. When a schema is available, you can access slot values directly as attributes (e.g., result.subject, result.predicate).
Attributes:
| Name | Type | Description |
|---|---|---|
data |
Dict[str, Any]
|
The raw result data as a dictionary |
score |
float
|
Similarity score (0-1, higher is better) |
id |
int
|
Row identifier in the collection |
Example
With Triple schema¶
results = hb.query("facts").find(subject="Alice") for r in results: ... print(f"{r.subject} {r.predicate} {r.object}") ... print(f"Score: {r.score:.3f}")
Dict-like access also works¶
print(r["subject"]) print(r.get("missing_field", "default"))
data
instance-attribute
¶
The raw result data as a dictionary.
score
instance-attribute
¶
Similarity score (0-1, higher is better).
__getitem__(key)
¶
Allow dict-like access: result['name']
get(key, default=None)
¶
Dict-like get with default.
to_dict()
¶
Convert to a plain dictionary.
Returns the data dict plus score and id.
hybi.compose.ComposeResultSet
dataclass
¶
A collection of ComposeResults with convenience methods.
Supports iteration, indexing, and bulk operations.
Example
results = hb.query("facts").find(subject="Alice") print(f"Found {len(results)} results") for r in results: ... print(r.object)
Get top result¶
best = results[0]
Convert all to dicts¶
dicts = results.to_list()
__iter__()
¶
__len__()
¶
first()
¶
Get the first result, or None if empty.
to_list()
¶
Convert all results to plain dictionaries.
to_dataframe()
¶
Convert results to a pandas DataFrame.
Returns:
| Type | Description |
|---|---|
DataFrame
|
pd.DataFrame with columns from data plus _score and _id |
filter(predicate)
¶
Filter results by a predicate function.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
predicate
|
Callable[[ComposeResult], bool]
|
Function that takes ComposeResult, returns bool |
required |
Returns:
| Type | Description |
|---|---|
ComposeResultSet
|
New ComposeResultSet with filtered results |