Query Patterns
Advanced querying with $hasDataType, $latest, and $not
Overview
LinkedRecords provides powerful query capabilities using special predicates and operators. This guide covers advanced querying techniques for filtering and finding attributes.
Basic Query Structure
Queries are expressed as objects where each key defines a named result set:
Query Predicates
$hasDataType
Filter by attribute type (KeyValueAttribute, LongTextAttribute, or BlobAttribute):
$latest(predicate)
Get the most recent value for a predicate. This is essential for state tracking:
$latest() is used when you track state changes over time by creating new facts
rather than deleting old ones. It returns attributes where the most recent fact
with that predicate matches the specified value.
$not(value)
Negation operator - find attributes where a predicate does NOT have a specific value:
Combining $latest and $not
The most common pattern is combining these for filtering by state:
Query by Attribute ID
Query specific attributes by their ID:
Compound Queries
Combine multiple criteria to narrow results:
This query finds:
- KeyValue attributes
- Classified as TodoList
- That are members of a specific collection
- Not archived (based on latest state)
- Where a specific organization is accountable
Relationship Queries
Find by Membership
Find by Custom Relationships
Find by Accountability
State Management Pattern
A common pattern is using separate state attributes to track item status.
Why Attributes Instead of Terms?
You might wonder: why create attributes for states instead of using terms directly
(e.g., [taskId, 'stateIs', 'Completed'])? The answer is permission control.
When states are attributes, you can use $canReferTo to control which users or
teams can set which states:
This enables granular workflows where different roles have different state transition permissions.
Implementation
Alternative: String-Based States
For simpler state tracking, you can use term values directly:
Note: "Completed" must be declared as a term
Multiple Result Sets
Fetch different categories in a single query:
Access Control in Queries
Queries automatically respect authorization - you only see attributes you have access to:
Loading Attribute Values
After querying, you can get attribute values:
Or use findAndLoadAll() for batch loading:
Query Performance Tips
-
Be specific - Include type filters (
isA) to narrow results quickly -
Use accountability filters - Filter by
$isAccountableForto scope to specific organizations -
Combine criteria - Multiple criteria help the query engine optimize
-
Avoid fetching everything - Query for what you need rather than loading all attributes and filtering client-side
Best Practices
-
Use $latest for state tracking instead of deleting old state facts
-
Create dedicated state attributes for reusable state markers
-
Combine $latest and $not for filtering out unwanted states
-
Use meaningful predicate names that describe the relationship
-
Structure queries logically with the most selective criteria first