Welcome to the SPARQL User Guide for Exocortex! This guide will teach you how to query your Obsidian vault using SPARQL, the powerful semantic query language for RDF data.
- Introduction to SPARQL in Exocortex
- Basic Queries
- Filtering and Conditions
- Working with Obsidian Properties
- Aggregations and Grouping
- Graph Construction
- Advanced Features (v2)
- Performance Best Practices
- Common Pitfalls and Solutions
- Security Considerations
SPARQL (SPARQL Protocol and RDF Query Language) is a standardized query language for RDF (Resource Description Framework) data. It allows you to search, retrieve, and manipulate structured knowledge represented as triples (subject-predicate-object).
Exocortex converts your Obsidian notes into RDF triples, enabling:
- Semantic Queries: Ask complex questions about relationships between notes
- Knowledge Discovery: Find hidden patterns and connections in your vault
- Dynamic Views: Generate live reports that update automatically
- Data Export: Export structured data for analysis or visualization
Every note in your vault becomes a set of RDF triples:
<note-path> <property> "value"
For example, a task note becomes:
<vault://Projects/My-Task.md> <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
<vault://Projects/My-Task.md> <https://exocortex.my/ontology/exo#Asset_label> "My Task" .
<vault://Projects/My-Task.md> <https://exocortex.my/ontology/ems#Task_status> "in-progress" .Create a code block with sparql language identifier:
```sparql
SELECT ?task ?label
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
?task <https://exocortex.my/ontology/exo#Asset_label> ?label .
}
```The results will appear live in your note and update automatically when your vault changes!
SELECT queries retrieve specific variables from your data.
SELECT ?task
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
}Explanation:
SELECT ?task- Return the?taskvariableWHERE { ... }- Pattern to match- Variables start with
?(e.g.,?task,?label)
SELECT ?task ?label
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
?task <https://exocortex.my/ontology/exo#Asset_label> ?label .
}Result:
| task | label |
|---|---|
vault://Tasks/Write-Report.md |
"Write Report" |
vault://Tasks/Review-Code.md |
"Review Code" |
SELECT ?s ?p ?o
WHERE {
?s ?p ?o .
}Warning: This returns ALL triples in your vault. Use LIMIT to avoid overwhelming results.
Control result size:
SELECT ?task ?label
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
?task <https://exocortex.my/ontology/exo#Asset_label> ?label .
}
LIMIT 10Pagination:
SELECT ?task ?label
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
?task <https://exocortex.my/ontology/exo#Asset_label> ?label .
}
LIMIT 10
OFFSET 20Remove duplicates:
SELECT DISTINCT ?status
WHERE {
?task <https://exocortex.my/ontology/ems#Task_status> ?status .
}Result: Unique list of all task statuses in your vault.
Filter results based on conditions:
SELECT ?task ?label
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
?task <https://exocortex.my/ontology/exo#Asset_label> ?label .
FILTER(regex(?label, "report", "i"))
}Explanation:
regex(?label, "report", "i")- Case-insensitive regex match- Finds all tasks with "report" in their label
SELECT ?task ?votes
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
?task <https://exocortex.my/ontology/ems#Effort_votes> ?votes .
FILTER(?votes > 5)
}Operators:
>,<,>=,<=- Numeric comparisons=,!=- Equality/inequality&&,||,!- Logical operators
SELECT ?task ?label ?status
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
?task <https://exocortex.my/ontology/exo#Asset_label> ?label .
?task <https://exocortex.my/ontology/ems#Task_status> ?status .
FILTER(?status = "in-progress" || ?status = "backlog")
FILTER(regex(?label, "urgent", "i"))
}Match optional properties:
SELECT ?task ?label ?priority
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
?task <https://exocortex.my/ontology/exo#Asset_label> ?label .
OPTIONAL {
?task <https://exocortex.my/ontology/ems#Task_priority> ?priority .
}
}Result: Includes tasks even if they don't have a priority property (will show null or empty).
Match either pattern:
SELECT ?asset ?label
WHERE {
{
?asset <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
} UNION {
?asset <https://exocortex.my/ontology/exo#Instance_class> "ems__Project" .
}
?asset <https://exocortex.my/ontology/exo#Asset_label> ?label .
}Result: All tasks and projects in your vault.
Exocortex uses two main property namespaces:
exo__- Core Exocortex properties (e.g.,exo__Asset_label,exo__Instance_class)ems__- Entity Model Schema classes (e.g.,ems__Task,ems__Project,ems__Area)
Full URIs:
exo__Asset_label → <https://exocortex.my/ontology/exo#Asset_label>
ems__Task → "ems__Task"
SELECT ?asset ?label ?class ?archived
WHERE {
?asset <https://exocortex.my/ontology/exo#Instance_class> ?class .
?asset <https://exocortex.my/ontology/exo#Asset_label> ?label .
OPTIONAL {
?asset <https://exocortex.my/ontology/exo#Asset_archived> ?archived .
}
}Properties:
exo__Asset_label- Display nameexo__Instance_class- Entity type (Task, Project, Area)exo__Asset_archived- Archival status
SELECT ?task ?label ?status ?priority ?votes
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
?task <https://exocortex.my/ontology/exo#Asset_label> ?label .
OPTIONAL { ?task <https://exocortex.my/ontology/ems#Task_status> ?status . }
OPTIONAL { ?task <https://exocortex.my/ontology/ems#Task_priority> ?priority . }
OPTIONAL { ?task <https://exocortex.my/ontology/ems#Effort_votes> ?votes . }
}Properties:
exo__Task_status- Task status (backlog, in-progress, done, archived)exo__Task_priority- Priority levelems__Effort_votes- Effort voting count
SELECT ?task ?project ?area
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
OPTIONAL {
?task <https://exocortex.my/ontology/ems#belongs_to_project> ?project .
}
OPTIONAL {
?project <https://exocortex.my/ontology/ems#belongs_to_area> ?area .
}
}Properties:
belongs_to_project- Task → Project relationshipbelongs_to_area- Project → Area relationship
SELECT ?asset ?label
WHERE {
?asset <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
?asset <https://exocortex.my/ontology/exo#Asset_label> ?label .
FILTER NOT EXISTS {
?asset <https://exocortex.my/ontology/exo#Asset_archived> ?archived .
FILTER(?archived = true || ?archived = "true" || ?archived = "archived")
}
}Explanation: Filters out assets with archived property set to true or "archived".
SELECT (COUNT(?task) AS ?taskCount)
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
}Result: Total number of tasks.
SELECT ?status (COUNT(?task) AS ?count)
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
?task <https://exocortex.my/ontology/ems#Task_status> ?status .
}
GROUP BY ?statusResult:
| status | count |
|---|---|
| "backlog" | 15 |
| "in-progress" | 7 |
| "done" | 42 |
SELECT ?project (SUM(?votes) AS ?totalVotes)
WHERE {
?task <https://exocortex.my/ontology/ems#belongs_to_project> ?project .
?task <https://exocortex.my/ontology/ems#Effort_votes> ?votes .
}
GROUP BY ?projectResult: Total effort votes per project.
SELECT ?project (COUNT(?task) AS ?taskCount)
WHERE {
?task <https://exocortex.my/ontology/ems#belongs_to_project> ?project .
}
GROUP BY ?project
HAVING (COUNT(?task) > 5)Result: Only projects with more than 5 tasks.
SELECT ?status
(COUNT(?task) AS ?taskCount)
(SUM(?votes) AS ?totalVotes)
(AVG(?votes) AS ?avgVotes)
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
?task <https://exocortex.my/ontology/ems#Task_status> ?status .
?task <https://exocortex.my/ontology/ems#Effort_votes> ?votes .
}
GROUP BY ?statusFunctions:
COUNT()- Count itemsSUM()- Sum numeric valuesAVG()- Average valuesMIN(),MAX()- Min/max values
Exocortex maps its custom ExoRDF properties to W3C standard RDF/RDFS vocabulary, enabling semantic web interoperability and inference.
| ExoRDF Property | RDF/RDFS Equivalent | Example |
|---|---|---|
| exo__Instance_class | rdf:type | ?asset rdf:type ems:Task |
| exo__Asset_isDefinedBy | rdfs:isDefinedBy | ?asset rdfs:isDefinedBy |
| exo__Class_superClass | rdfs:subClassOf | ?class rdfs:subClassOf exo:Asset |
| exo__Property_range | rdfs:range | ?property rdfs:range xsd:string |
| exo__Property_domain | rdfs:domain | ?property rdfs:domain ems:Task |
| exo__Property_superProperty | rdfs:subPropertyOf | ?prop rdfs:subPropertyOf rdf:type |
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX exo: <https://exocortex.my/ontology/exo#>
SELECT ?asset ?type ?label
WHERE {
?asset rdf:type ?type .
?type rdfs:subClassOf* exo:Asset .
?asset exo:Asset_label ?label .
}
ORDER BY ?type ?labelThis query returns ALL assets (tasks, projects, areas) by leveraging the rdfs:subClassOf* transitive property. The * means "zero or more" subclass relationships.
- Semantic Interoperability - Queries work with any RDF tool
- Inference - Automatic reasoning over class hierarchies
- Standardization - Well-known predicates, better tooling
- Compatibility - Export data to other semantic web systems
CONSTRUCT queries create new RDF triples instead of returning table results.
CONSTRUCT {
?task <http://exocortex.ai/ontology#has_label> ?label .
}
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
?task <https://exocortex.my/ontology/exo#Asset_label> ?label .
}Result: Returns triples (subject-predicate-object) instead of table rows.
CONSTRUCT {
?task <http://exocortex.ai/ontology#in_area> ?area .
}
WHERE {
?task <https://exocortex.my/ontology/ems#belongs_to_project> ?project .
?project <https://exocortex.my/ontology/ems#belongs_to_area> ?area .
}Result: Directly links tasks to their areas (skipping intermediate project).
CONSTRUCT {
?task <http://example.org/priority_level> ?priorityClass .
}
WHERE {
?task <https://exocortex.my/ontology/ems#Effort_votes> ?votes .
BIND(
IF(?votes > 10, "high",
IF(?votes > 5, "medium", "low")
) AS ?priorityClass
)
}Result: Classifies tasks into priority levels based on votes.
CONSTRUCT results can be exported as Turtle (.ttl) files using the export button in the query result viewer.
SPARQL Engine v2 adds several powerful features for complex queries.
BIND creates new variable bindings from expressions.
SELECT ?task ?label ?displayLabel
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
?task <https://exocortex.my/ontology/exo#Asset_label> ?label .
BIND(CONCAT("Task: ", ?label) AS ?displayLabel)
}Key Points:
- BIND appears within the WHERE clause
- The bound variable can be used in later patterns
- Use for computed values, type conversions, and formatting
Create conditional values:
SELECT ?task ?votes ?urgency
WHERE {
?task <https://exocortex.my/ontology/ems#Effort_votes> ?votes .
BIND(IF(?votes > 5, "urgent", "normal") AS ?urgency)
}Supported Functions in BIND:
- String:
CONCAT(),STR(),STRLEN(),UCASE(),LCASE(),REPLACE() - Numeric:
+,-,*,/,ABS(),ROUND(),CEIL(),FLOOR() - Conditional:
IF(),COALESCE(),BOUND() - Type:
DATATYPE(),LANG(),IRI(),BNODE()
Test for pattern existence without binding variables.
Check if a pattern exists:
SELECT ?project ?label
WHERE {
?project <https://exocortex.my/ontology/exo#Instance_class> "ems__Project" .
?project <https://exocortex.my/ontology/exo#Asset_label> ?label .
FILTER EXISTS {
?task <https://exocortex.my/ontology/ems#belongs_to_project> ?project .
?task <https://exocortex.my/ontology/ems#Task_status> "in-progress" .
}
}Result: Projects with at least one in-progress task.
Check if a pattern does NOT exist:
SELECT ?task ?label
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
?task <https://exocortex.my/ontology/exo#Asset_label> ?label .
FILTER NOT EXISTS {
?task <https://exocortex.my/ontology/exo#Asset_archived> "true" .
}
}Result: All non-archived tasks.
Use EXISTS when:
- You only need to check for presence/absence
- You don't need the matched values
Use OPTIONAL when:
- You need the matched values in results
- Missing values should be null, not filtered out
Navigate graph relationships with path expressions.
| Operator | Meaning | Example |
|---|---|---|
/ |
Sequence | a/b matches a then b |
| |
Alternative | a|b matches a OR b |
^ |
Inverse | ^a matches reverse of a |
+ |
One or more | a+ matches a, a/a, a/a/a, ... |
* |
Zero or more | a* matches self, a, a/a, ... |
? |
Zero or one | a? matches self OR a |
Match predicates in order:
SELECT ?task ?area
WHERE {
?task <https://exocortex.my/ontology/ems#belongs_to_project>/<https://exocortex.my/ontology/ems#belongs_to_area> ?area .
}Explanation: Task → Project → Area in two hops.
Match any of several predicates:
SELECT ?asset ?parent
WHERE {
?asset (<https://exocortex.my/ontology/ems#belongs_to_project>|<https://exocortex.my/ontology/ems#belongs_to_area>) ?parent .
}Reverse the direction:
SELECT ?project ?task
WHERE {
?project ^<https://exocortex.my/ontology/ems#belongs_to_project> ?task .
}Explanation: Find tasks that belong to project (reverse of "task belongs_to project").
+ requires at least one step:
SELECT ?task ?ancestor
WHERE {
?task <https://exocortex.my/ontology/ems#belongs_to_project>+ ?ancestor .
}* includes zero steps (self):
SELECT ?node ?related
WHERE {
?node <https://exocortex.my/ontology/ems#belongs_to_area>* ?related .
}Performance Note: Property paths use BFS traversal with cycle detection. Maximum depth is 100 to prevent infinite loops.
Match zero or one step:
SELECT ?task ?maybeProject
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
?task <https://exocortex.my/ontology/ems#belongs_to_project>? ?maybeProject .
}Result: Tasks and their projects (or null if no project).
Use queries within queries for complex operations.
SELECT ?task ?taskLabel ?projectTaskCount
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
?task <https://exocortex.my/ontology/exo#Asset_label> ?taskLabel .
?task <https://exocortex.my/ontology/ems#belongs_to_project> ?project .
{
SELECT ?project (COUNT(?t) AS ?projectTaskCount)
WHERE {
?t <https://exocortex.my/ontology/ems#belongs_to_project> ?project .
}
GROUP BY ?project
}
}Explanation: Each task shows its project's total task count.
Find tasks in projects with more than 5 tasks:
SELECT ?task ?label
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
?task <https://exocortex.my/ontology/exo#Asset_label> ?label .
?task <https://exocortex.my/ontology/ems#belongs_to_project> ?project .
{
SELECT ?project
WHERE {
SELECT ?project (COUNT(?t) AS ?count)
WHERE {
?t <https://exocortex.my/ontology/ems#belongs_to_project> ?project .
}
GROUP BY ?project
HAVING (?count > 5)
}
}
}- Keep subqueries simple - Complex nesting hurts readability
- Use aggregations in subqueries - Main use case for subqueries
- Avoid excessive nesting - Two levels is usually the practical maximum
- Consider alternatives - Sometimes OPTIONAL or EXISTS is cleaner
❌ Slow:
SELECT ?s ?p ?o
WHERE {
?s ?p ?o .
}
LIMIT 100✅ Fast:
SELECT ?task ?label
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
?task <https://exocortex.my/ontology/exo#Asset_label> ?label .
}Why: Specific patterns leverage indexing (SPO, POS, OSP indexes).
Always use LIMIT when exploring:
SELECT ?s ?p ?o
WHERE {
?s ?p ?o .
}
LIMIT 10Why: Prevents overwhelming results and browser lag.
❌ Slow:
SELECT ?task ?label
WHERE {
?task <https://exocortex.my/ontology/exo#Asset_label> ?label .
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
FILTER(regex(?label, "report", "i"))
}✅ Fast:
SELECT ?task ?label
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
?task <https://exocortex.my/ontology/exo#Asset_label> ?label .
FILTER(regex(?label, "report", "i"))
}Why: Filtering on class first reduces candidate set before string matching.
❌ Slower:
SELECT ?task ?label ?priority
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
OPTIONAL { ?task <https://exocortex.my/ontology/exo#Asset_label> ?label . }
OPTIONAL { ?task <https://exocortex.my/ontology/ems#Task_priority> ?priority . }
}✅ Faster:
SELECT ?task ?label
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
?task <https://exocortex.my/ontology/exo#Asset_label> ?label .
}Why: OPTIONAL patterns disable some optimizations. Only use when needed.
DISTINCT has overhead. Only use when necessary:
SELECT ?status
WHERE {
?task <https://exocortex.my/ontology/ems#Task_status> ?status .
}When to use DISTINCT: When you expect duplicates and need unique values.
❌ Wrong:
SELECT ?task
WHERE
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .✅ Correct:
SELECT ?task
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
}Error: Expected WHERE clause
❌ Wrong:
SELECT ?task ?label
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task"
?task <https://exocortex.my/ontology/exo#Asset_label> ?label .
}✅ Correct:
SELECT ?task ?label
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
?task <https://exocortex.my/ontology/exo#Asset_label> ?label .
}Error: Each triple pattern must end with . (except the last one, which is optional).
❌ Wrong:
SELECT ?task
WHERE {
?task exo__Instance_class "ems__Task" .
}✅ Correct:
SELECT ?task
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
}Error: Properties must be full URIs in angle brackets.
SPARQL is case-sensitive:
❌ Wrong:
select ?task
where {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
}✅ Correct:
SELECT ?task
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
}Best Practice: Use uppercase keywords (SELECT, WHERE, FILTER).
❌ Wrong:
SELECT ?task
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> ems__Task .
}✅ Correct:
SELECT ?task
WHERE {
?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" .
}Error: String literals must be quoted. ems__Task without quotes is treated as a variable.
Debugging Checklist:
-
Check property URIs:
SELECT ?s ?p ?o WHERE { ?s ?p ?o . } LIMIT 10
Verify actual property names in your vault.
-
Check class values:
SELECT DISTINCT ?class WHERE { ?s <https://exocortex.my/ontology/exo#Instance_class> ?class . }
Verify actual class names (
ems__Task, notTask). -
Check property existence:
SELECT ?task WHERE { ?task <https://exocortex.my/ontology/exo#Instance_class> "ems__Task" . }
Verify tasks exist in your vault with correct frontmatter.
Problem: Query executes without errors but returns 0 results.
Root Cause: Namespace URIs in query don't match actual URIs used in triple store.
Diagnostic Query:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?predicate
WHERE {
?subject ?predicate ?object .
}
LIMIT 20If you see predicates like http://exocortex.org/ontology/Asset_label but your query uses:
PREFIX exo: <https://exocortex.my/ontology/exo#>That's a mismatch!
Solution:
- Check vault ontology files (
!exo.md,!ems.md) for canonical URIs inexo__Ontology_urlproperty - Update PREFIX declarations to match:
PREFIX exo: <https://exocortex.my/ontology/exo#> PREFIX ems: <https://exocortex.my/ontology/ems#>
- Use hash-style URIs (
#at end), not slash-style (/at end)
Reference: See PR #363 for namespace unification example.
Symptom: Query returns empty results despite assets existing.
Cause: RDF/RDFS triples not generated (mapping not enabled).
Solution:
- Verify triple store includes RDF/RDFS triples:
SELECT * WHERE { ?s ?p ?o } LIMIT 100
- Check for rdfs:subClassOf triples
- Rebuild triple store: Command Palette → "Reload Layout"
Symptom: Transitive queries take >1 second.
Cause: Large result set, no LIMIT.
Solution:
- Add LIMIT clause
- Filter by specific type before transitive closure
- Use ExoRDF queries if performance critical
Symptom: Query returns blank nodes instead of URIs.
Cause: Assets missing exo__Asset_uid property.
Solution:
- Check asset frontmatter for exo__Asset_uid
- Run "Repair Folder" command to add missing UIDs
- Rebuild triple store
Symptom: Error: "Invalid ontology URL"
Cause: Asset references non-existent ontology file.
Solution:
- Verify exo__Asset_isDefinedBy references valid file
- Check ontology file has exo__Ontology_url property
- Use default ontology URL if needed
This section documents security-relevant SPARQL functions and their appropriate use cases.
The RAND() function returns a pseudo-random number in the range [0, 1) as defined in the W3C SPARQL 1.1 specification:
# Random sampling - get 10 random tasks
SELECT ?task ?label
WHERE {
?task exo:Instance_class "ems__Task" .
?task exo:Asset_label ?label .
}
ORDER BY RAND()
LIMIT 10
⚠️ Important:RAND()uses standard pseudo-random number generation (JavaScript'sMath.random()), which is NOT cryptographically secure.
Appropriate uses:
- ✅ Random sampling of query results
- ✅ Shuffling result order
- ✅ Statistical sampling for testing
- ✅ Non-security randomization in queries
DO NOT use for:
- ❌ Generating security tokens
- ❌ Cryptographic key generation
- ❌ Session identifiers
- ❌ Any security-critical purpose
This is intentional per the SPARQL 1.1 specification which does not require cryptographic randomness for this function.
Exocortex implements the standard SPARQL 1.1 hash functions as defined in the W3C specification:
| Function | Algorithm | Security Status |
|---|---|---|
MD5(str) |
MD5 | |
SHA1(str) |
SHA-1 | |
SHA256(str) |
SHA-256 | ✅ Secure |
SHA384(str) |
SHA-384 | ✅ Secure |
SHA512(str) |
SHA-512 | ✅ Secure |
⚠️ WARNING: MD5 and SHA1 are cryptographically broken and should NOT be used for security purposes (passwords, authentication, digital signatures).
These functions exist in Exocortex only for SPARQL 1.1 specification compliance. They are appropriate for:
- ✅ Data deduplication (finding identical content)
- ✅ Checksums for change detection
- ✅ Query result caching keys
- ✅ Non-security fingerprinting
DO NOT use for:
- ❌ Password hashing
- ❌ Authentication tokens
- ❌ Cryptographic signatures
- ❌ Any security-critical purpose
When you have a choice, prefer SHA256(), SHA384(), or SHA512():
# Preferred - SHA-256 for content hashing
SELECT ?file (SHA256(?content) AS ?hash)
WHERE {
?file exo:Asset_content ?content .
}- CWE-327: Use of Broken or Risky Cryptographic Algorithm
- CWE-338: Use of Cryptographically Weak PRNG
- SPARQL 1.1 Hash Functions Specification
- SPARQL 1.1 RAND() Function Specification
- Explore Examples: See Query-Examples.md for 20+ real-world query patterns
- Performance Tuning: Read Performance-Tips.md for optimization techniques
- Developer Guide: Learn about the architecture in Developer-Guide.md
Need Help? Open an issue on GitHub or ask in the community discussions!